Osadzanie ikon w aplikacji WPF jako zasobu

Próbuję osadzić ikonę w mojej aplikacji WPF, aby móc wyciągnąć ją do użycia jako ikona w JumpList systemu Windows 7 za pomocą następującego kodu:

newScene.IconResourcePath = System.Reflection.Assembly.GetEntryAssembly().Location;
newScene.IconResourceIndex = 0;

Udało mi się go uruchomić przy użyciu następującej metody: http://dennisdel.com/?p=38

Jednak nie wydaje się to najlepszym podejściem i wydaje się, że powinien być łatwiejszy sposób osadzenia zasobu ikon w mojej aplikacji, pozostawiając zaznaczoną opcję" Icon and Manifest " Właściwości aplikacji dla mojego programu.

Próbowałem wielu metod, w tym ustawienie akcji icon build jako zasobu i osadzonego zasobu, ale za każdym razem otwieram mój .exe w edytorze zasobów ikona nie pojawia się.

Jakieś sugestie?
Author: BoltClock, 2010-06-11

1 answers

Visual Studio nie ma sposobu na wykonanie kompilatora zasobów Win32 z zadania MSBuild, a żadna z jego wbudowanych funkcji do tworzenia zasobów utworzonych przez surowce. Z tego powodu twoje wybory to:

  1. Utwórz .plik res "ręcznie", jak opisano w linkowanym artykule, lub
  2. Dodaj zadanie budowania, aby można było wywołać kompilator zasobów Win32 z twojego .csproj

Najpierw wyjaśnię różnice między pięcioma różnymi rodzajami z "zasobów", które mogą istnieć wexe lub .plik dll, w tym "zasoby Win32" wymagane przez JumpList.

Następnie wyjaśnię, jak skonstruować niestandardowe zadanie budowania, które pozwala osadzać dowolne zasoby Win32 w C# lub VB.NET wykonywalny.


5 rodzajów zasobów w pliku wykonywalnym Win32]}

Istnieje pięć różnych rodzajów "zasobów", które mogą istnieć w .exe lub .plik dll:

  • Zasoby Win32
  • NET Framework " Embedded Zasoby "
  • [[24]}obiekty CLR w zasobach
  • XAML Resources
  • WPF Resources (obiekty w zasobach)

Zasoby Win32

Oryginalnym rodzajem zasobu był "zasób" Win32. Ten rodzaj zasobu jest zdefiniowany wplik rc i ma numerowane lub nazwane zasoby, z których każdy ma typ i blob danych.
Win32 resource compiler, rc.exe, kompiluje .plik rc do pliku binarnego .plik res może wtedy być dodane do wynikowego pliku wykonywalnego.

Zasoby Win32 są dostępne za pomocą funkcji Win32 FindResource i LoadResource.

Zasoby Win32 są osadzane w aplikacjach C++, dodając je doplik rc, który jest kompilowany doplik res i podłączony do pliku wykonywalnego. Można je również dodać po fakcie za pomocą rc.program exe. Dla C # i VB.NET aplikacje, MSBuild może dodać prebuilt .plik res do pliku wykonywalnego, który tworzy za pomocą kompilatora Csc lub Vbc lub może zbudować domyślne dla Ciebie. Ani C#, ani VB.NET posiada możliwość budowania niestandardowego .pliki res z .pliki rc, i nie ma zadania MSBuild, aby to zrobić za Ciebie.

Możesz przeglądać zasoby Win32 wexe lub .dll otwierając .exe lub .sam plik dll w Visual Studio używając File - > Open.

Typowa aplikacja C, C++ lub MFC będzie miała wiele zasobów Win32, na przykład każde okno dialogowe będzie określone przez zasób.

Typowa aplikacja WPF będzie miała tylko trzy domyślne zasoby Win32 skonstruowane przez C # lub VB.NET kompilator: zasób wersji, RT_MANIFEST i ikona aplikacji. Zawartość tych zasobów jest zbudowana z atrybutów asemblera w kodzie i elementu <ApplicationIcon> w .csproj lub .plik vbproj.

Jest to rodzaj zasobu, którego szuka JumpList.

Embedded Resources

"zasób Wbudowany" to zasób NET Framework. Struktura danych zawierająca zasoby te są zarządzane przez CLR w sposób bardziej sprzyjający dostępowi przez kod zarządzany. Każdy zasób jest identyfikowany za pomocą nazwy łańcuchowej, która zgodnie z konwencją zaczyna się od przestrzeni nazw klasy, z którą zasób jest skojarzony.

Zasób Wbudowany to tylko blob danych binarnych z nazwą. Rzeczywisty typ danych jest znany przez wywołującego lub wywnioskowany z nazwy, podobnie jak pliki w systemie plików. Na przykład zasób osadzony z nazwą kończącą się na ".jpg " prawdopodobnie być plikiem JPEG.

Dostęp do zasobów wbudowanych można uzyskać za pomocą aplikacji Assembly.GetManifestResourceStream i jej rodzeństwa GetManifestResourceInfo i GetManifestResourceNames.

Wbudowane zasoby są wbudowane .exe i .pliki dll poprzez dodanie pliku do projektu i ustawienie akcji budowania na "osadzony zasób".

Możesz wyświetlić osadzone zasoby w .exe lub .dll otwierając go w Net Reflector i patrząc na folder "Resources".

[21]}osadzone zasoby są powszechnie używane w WinForms, ale prawie nigdy z WPF.

Zestawy Zasobów (.resx/zasoby)

Wiele obiektów NET Framework, takich jak ciągi znaków i ikony, można łączyć ze sobą w jeden "zestaw zasobów" struture danych, który jest przechowywany w .exe jako pojedynczy Net Framework Embedded Resource. Na przykład jest to używane przez WinForms do przechowywania rzeczy takich jak ikony i ciągi znaków, które nie są łatwe do włączenia do wygenerowanego kodu.

Obiekty w zestawie zasobów mogą być pobierane indywidualnie za pomocą ResourceManager i ResourceSet klasy określone przez CLR.

Obiekty w zbiorze zasobów są zdefiniowane w kodzie źródłowym przez a .plik resx. Dane mogą być bezpośrednio w .plik resx (jak w przypadku ciągów) lub odwołuje się do .plik resx (jak w przypadku ikon). Gdy projekt jest zbudowany, zawartość określona przez każdego .pliki resx są serializowane w postaci binarnej i przechowywane jako pojedynczy zasób osadzony z rozszerzeniem".resx "zastąpiony przez".zasoby".

Możesz przeglądać obiekty w zasobie ustawionym przez otwieranie .exe lub .dll w Net Reflector, otwierając folder Resources, klikając na ".zasobów", oraz przeglądanie elementów znajdujących się w prawym okienku.

Wiele powszechnie używanych funkcji ery WinForms .pliki i zasoby resx w sposób podobny do starego Win32 .pliki rc, do przechowywania wielu zasobów, takich jak łańcuchy wszystkie razem. Są one również używane przez samą WinForms do przechowywania ustawień w formularzu, który nie może być umieszczony w kodzie za.

Aplikacje WPF prawie nigdy nie używają dowolne obiekty w zasobach, choć sam WPF używa zasobów wewnętrznie do przechowywania skompilowanego XAML.

Zasoby XAML

Zasób WPF XAML jest skompilowanym plikiem XAML przechowywanym wewnątrz zasobu. Nazwa wewnątrz zestawu zasobów jest oryginalną nazwą pliku z ".XAML "zastąpiony przez".g. baml". Zawartość może być dowolną poprawną wersją XAML, najczęściej spotykanymi typami są Window, Page, UserControl, ResourceDictionary i
Podanie.

WPF Resources może być załadowany za pomocą Application.LoadComponent() lub odwołując się do oryginalnej nazwy pliku XAML w kontekście WPF. Ponadto każdy zasób WPF, który ma kod za sobą (określony przez x:Class), zostanie automatycznie załadowany i zastosowany do każdego obiektu, który zostanie utworzony w tej klasie podczas jego wywołania InitializeComponent.

Zasoby WPF są tworzone przez dodanie a .plik xaml do projektu i ustawienie jego akcji budowania na "Resource"," Page " lub "ApplicationDefinition". Powoduje to, że kompilator skompiluje plik do BAML i doda it do odpowiedniego zasobu.

Możesz zobaczyć zasoby XAML w .exe lub .dll otwierając go w Net Reflector z zainstalowanym dodatkiem BamlViewer, wybierając z menu Tools -> BAML Viewer i używając przeglądarki BAML do przeglądania konkretnego .plik g. baml wewnątrz .zasoby.

WPF Resources within a ResourceDictionary

W WPF prawie wszystkie tak zwane "zasoby" są wpisami w ResourceDictionary. Pomysłodawcami są opisane w XAML, albo w innych obiektach, takich jak Windows i UserControls, albo w oddzielnych plikach XAML, które zawierają tylko ResourceDictionary. Każdy z nich jest identyfikowany przez "X:Key", który może być dowolnym typem obiektu. Same zasoby mogą być również dowolnym typem obiektu.

[21]} zasoby WPF mogą być odwoływane w XAML za pomocą rozszerzeń znaczników {StaticResource} i {DynamicResource} lub mogą być ładowane w kodzie za pomocą FindResource.

Zasoby WPF są dodawane do ResourceDictionary przez dodanie ich do pliku XAML który zawiera ResourceDictionary wewnątrz elementu <ResourceDictionary> i nadaje im atrybut x:Key.

Zasoby WPF są szeroko wykorzystywane w WPF, w tym pędzle, style, dane, geometrie, szablony itp.

Możesz przeglądać zasoby WPF w .exe lub .dll przeglądając zasoby XAML jak opisano powyżej i dla każdego z nich patrząc wewnątrz znaczników ResourceDictionary, aby zobaczyć same zasoby.


W tym zasoby Win32 w C # lub VB.NET wykonywalny

Jak łatwo osadzić dowolne zasoby Win32 w C # lub VB.NET .exe

Zauważysz z powyższej dyskusji, że łatwo jest dodać każdy rodzaj zasobu do swojego C # lub VB.NET aplikacja z wyjątkiem dla zasobów Win32. Aby to ułatwić, możesz dodać dodatkowe zadanie budowania i cel. Oto jak:

  1. Zbuduj projekt zawierający pojedynczy "Win32ResourceCompiler" zbuduj zadanie i skompiluj je
  2. Create a .targets plik, który zawiera pojedynczy cel, który używa tego zadania do automatycznego budowania .plik rc do a .res
  3. Ustaw projekt tak, aby korzystał z wynikowych .plik res

Zadanie jest niezwykle proste:

public class Win32ResourceCompiler : ToolTask
{
  public ITaskItem Source { get; set; }
  public ITaskItem Output { get; set; }

  protected override string ToolName { get { return "rc.exe"; } }

  protected override string GenerateCommandLineCommands()
  {
    return @"/r /fo """ + Output.ItemSpec + @""" """ + Source.ItemSpec + @"""";
  }

  protected override string GenerateFullPathToTool()
  {
    // TODO: Return path to rc.exe in your environment
  }
}

The .plik targets jest również bardzo prosty. To będzie coś w tym stylu:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <UsingTask TaskName="SomeNamespace.Win32ResourceCompiler" AssemblyFile="Something.dll" />

  <PropertyGroup>
    <CoreCompileDependsOn>$(CoreCompileDependsOn);CompileWin32RCFile</CoreCompileDependsOn>
  </PropertyGroup>

  <Target Name="CompileWin32RCFile" Outputs="@(Win32RCFile->'%(filename).res')">
    <Win32ResourceCompiler
      Source="@(Win32RCFile)"
      Output="@(Win32RCFile->'%(filename).res')" />
  </Target>
</Project>
Teraz w Twoim .plik csproj, dodaj odniesienie do swojego .plik celów:
<Import Project="Win32ResourceCompiler.targets" />

I oczywiście trzeba dać swoje .plik rc Typ pliku Win32RCFile:

<ItemGroup>
  <Win32RCFile Include="MyWin32Resources.rc" />
</ItemGroup>

Dzięki tej konfiguracji możesz utworzyć tradycyjny Win32 .plik rc, aby określić wszystkie zasoby Win32, w tym wersję, manifest, ikonę aplikacji i tyle dodatkowych ikon, ile chcesz. Za każdym razem, gdy kompilujesz, wszystkie te zasoby Win32 zostaną dodane do twojego .plik exe.

Konfiguracja zajmuje trochę czasu, ale jest o wiele bardziej satysfakcjonująca i prostsza na dłuższą metę niż ręczna edycja a .plik res.

Możesz określić wiele ikon w Twoje .plik rc taki:

1 ICON ApplicationIcon.ico
2 ICON JumpListIcon.ico
3 ICON AnotherIcon.ico

Tutaj {[163] } jest dokumentacja dla wszystkich instrukcji definicji zasobów, których można użyć w .plik rc.

Należy również zauważyć, że powyższe .plik targets został wpisany pod wpływem chwili i nie został przetestowany. Dokumentacja składni MSBuild (.csproj i .cele) pliki można znaleźć tutaj i tutaj , i dobre przykłady .pliki docelowe można znaleźć w c:\Windows\Microsoft.NET\Framework\v3.5 katalog).

 27
Author: Ray Burns,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-15 05:45:31