Tworzenie plików zasobów dla aplikacji platformy .NET

Zasoby, takie jak ciągi, obrazy lub dane obiektów, można uwzględnić w plikach zasobów, aby były łatwo dostępne dla aplikacji. Program .NET Framework oferuje pięć sposobów tworzenia plików zasobów:

  • Utwórz plik tekstowy zawierający zasoby ciągów. Możesz użyć generatora plików zasobów (resgen.exe), aby przekonwertować plik tekstowy na plik zasobu binarnego (resources). Następnie możesz osadzić plik binarny zasobów w pliku wykonywalnym aplikacji lub bibliotece aplikacji przy użyciu kompilatora języka lub osadzić go w zestawie satelitarnym przy użyciu konsolidatora zestawów (Al.exe). Aby uzyskać więcej informacji, zobacz sekcję Zasoby w plikach tekstowych.

  • Utwórz plik zasobu XML (resx), który zawiera dane ciągu, obrazu lub obiektu. Możesz użyć generatora plików zasobów (resgen.exe), aby przekonwertować plik resx na plik zasobu binarnego (resources). Następnie możesz osadzić plik binarny zasobów w pliku wykonywalnym aplikacji lub bibliotece aplikacji przy użyciu kompilatora języka lub osadzić go w zestawie satelitarnym przy użyciu konsolidatora zestawów (Al.exe). Aby uzyskać więcej informacji, zobacz sekcję Zasoby w plikach resx.

  • Programowe tworzenie pliku zasobu XML (resx) przy użyciu typów w System.Resources przestrzeni nazw. Możesz utworzyć plik resx, wyliczyć jego zasoby i pobrać określone zasoby według nazwy. Aby uzyskać więcej informacji, zobacz Praca z plikami resx programowo.

  • Programowe tworzenie pliku zasobu binarnego (.resources). Następnie możesz osadzić plik w pliku wykonywalnym aplikacji lub bibliotece aplikacji przy użyciu kompilatora języka lub osadzić go w zestawie satelitarnym przy użyciu konsolidatora zestawów (Al.exe).. Aby uzyskać więcej informacji, zobacz sekcję Zasoby w plikach resources .

  • Użyj programu Visual Studio , aby utworzyć plik zasobu i dołączyć go do projektu. Program Visual Studio udostępnia edytor zasobów, który umożliwia dodawanie, usuwanie i modyfikowanie zasobów. W czasie kompilacji plik zasobu jest automatycznie konwertowany na binarny plik resources i osadzony w zestawie aplikacji lub zestawie satelitarnym. Aby uzyskać więcej informacji, zobacz sekcję Pliki zasobów w programie Visual Studio .

Zasoby w plikach tekstowych

Do przechowywania tylko zasobów ciągów można użyć plików tekstowych (.txt lub restext). W przypadku zasobów innych niż ciąg użyj plików resx lub utwórz je programowo. Pliki tekstowe zawierające zasoby ciągów mają następujący format:

# This is an optional comment.
name = value

; This is another optional comment.
name = value

; The following supports conditional compilation if X is defined.
#ifdef X
name1=value1
name2=value2
#endif

# The following supports conditional compilation if Y is undefined.
#if !Y
name1=value1
name2=value2
#endif

Format pliku zasobów .txt i plików restext jest identyczny. Rozszerzenie pliku restext służy jedynie do natychmiastowego identyfikacji plików tekstowych jako plików zasobów opartych na tekście.

Zasoby ciągów są wyświetlane jako pary nazwa/wartość , gdzie nazwa jest ciągiem identyfikującym zasób, a wartość jest ciągiem zasobu zwracanym podczas przekazywania nazwy do metody pobierania zasobów, takiej jak ResourceManager.GetString. nazwa i wartość muszą być oddzielone znakiem równości (=). Na przykład:

FileMenuName=File
EditMenuName=Edit
ViewMenuName=View
HelpMenuName=Help

Uwaga

Nie używaj plików zasobów do przechowywania haseł, informacji poufnych zabezpieczeń ani danych prywatnych.

Puste ciągi (czyli zasób, którego wartość jest String.Empty) są dozwolone w plikach tekstowych. Na przykład:

EmptyString=

Począwszy od programu .NET Framework 4.5 i we wszystkich wersjach platformy .NET Core, pliki tekstowe obsługują kompilację warunkową z konstrukcjami #ifdefsymboli... #endif i#if ! symboli. #endif Następnie możesz użyć przełącznika /define z generatorem plików zasobów (resgen.exe), aby zdefiniować symbole. Każdy zasób wymaga własnego #ifdefsymbolu... #endif lub #if !konstrukcji symbolu... #endif Jeśli używasz instrukcji #ifdef i symbolu jest zdefiniowana, skojarzony zasób jest uwzględniony w pliku resources; w przeciwnym razie nie jest dołączony. Jeśli używasz instrukcji #if ! i symbolu nie jest zdefiniowany, skojarzony zasób zostanie uwzględniony w pliku resources. W przeciwnym razie nie zostanie uwzględniony.

Komentarze są opcjonalne w plikach tekstowych i poprzedzone średnikiem (;) lub znakiem funta (#) na początku wiersza. Wiersze zawierające komentarze można umieścić w dowolnym miejscu w pliku. Komentarze nie są uwzględniane w skompilowanym pliku resources, który jest tworzony przy użyciu generatora plików zasobów (resgen.exe).

Wszystkie puste wiersze w plikach tekstowych są uważane za białe znaki i są ignorowane.

W poniższym przykładzie zdefiniowano dwa zasoby ciągów o nazwie OKButton i CancelButton.

#Define resources for buttons in the user interface.
OKButton=OK
CancelButton=Cancel

Jeśli plik tekstowy zawiera zduplikowane wystąpienia nazwy, generator plików zasobów (resgen.exe) wyświetla ostrzeżenie i ignoruje drugą nazwę.

wartość nie może zawierać nowych znaków wiersza, ale można użyć znaków ucieczki w stylu języka C, takich jak \n reprezentowanie nowego wiersza i \t reprezentowania karty. Możesz również dołączyć znak ukośnika odwrotnego, jeśli zostanie on uniknięci (na przykład "\\"). Ponadto dozwolony jest pusty ciąg.

Zapisz zasoby w formacie pliku tekstowego przy użyciu kodowania UTF-8 lub kodowania UTF-16 w kolejności bajtów little-endian lub big-endian. Jednak generator plików zasobów (resgen.exe), który konwertuje plik .txt na plik resources, traktuje pliki jako UTF-8 domyślnie. Jeśli chcesz Resgen.exe rozpoznać plik, który został zakodowany przy użyciu formatu UTF-16, musisz dołączyć znak kolejności bajtów Unicode (U+FEFF) na początku pliku.

Aby osadzić plik zasobu w formacie tekstowym w zestawie .NET, należy przekonwertować plik na plik zasobu binarnego (resources) przy użyciu generatora plików zasobów (resgen.exe). Następnie można osadzić plik resources w zestawie .NET przy użyciu kompilatora języka lub osadzić go w zestawie satelitarnym przy użyciu konsolidatora zestawów (Al.exe).

W poniższym przykładzie użyto pliku zasobu w formacie tekstowym o nazwie GreetingResources.txt dla prostej aplikacji konsolowej "Hello World". Plik tekstowy definiuje dwa ciągi i promptgreeting, które monitują użytkownika o wprowadzenie nazwy i wyświetlenie powitania.

# GreetingResources.txt
# A resource file in text format for a "Hello World" application.
#
# Initial prompt to the user.
prompt=Enter your name:
# Format string to display the result.
greeting=Hello, {0}!

Plik tekstowy jest konwertowany na plik resources przy użyciu następującego polecenia:

resgen GreetingResources.txt

Poniższy przykład przedstawia kod źródłowy aplikacji konsolowej, która używa pliku resources do wyświetlania komunikatów użytkownikowi.

using System;
using System.Reflection;
using System.Resources;

public class Example
{
   public static void Main()
   {
      ResourceManager rm = new ResourceManager("GreetingResources",
                               typeof(Example).Assembly);
      Console.Write(rm.GetString("prompt"));
      string name = Console.ReadLine();
      Console.WriteLine(rm.GetString("greeting"), name);
   }
}
// The example displays output like the following:
//       Enter your name: Wilberforce
//       Hello, Wilberforce!
Imports System.Reflection
Imports System.Resources

Module Example
    Public Sub Main()
        Dim rm As New ResourceManager("GreetingResources",
                                      GetType(Example).Assembly())
        Console.Write(rm.GetString("prompt"))
        Dim name As String = Console.ReadLine()
        Console.WriteLine(rm.GetString("greeting"), name)
    End Sub
End Module
' The example displays output like the following:
'       Enter your name: Wilberforce
'       Hello, Wilberforce!

Jeśli używasz języka Visual Basic, a plik kodu źródłowego nosi nazwę Greeting.vb, następujące polecenie tworzy plik wykonywalny zawierający osadzony plik resources:

vbc greeting.vb -resource:GreetingResources.resources

Jeśli używasz języka C#, a plik kodu źródłowego nosi nazwę Greeting.cs, następujące polecenie tworzy plik wykonywalny zawierający osadzony plik resources:

csc greeting.cs -resource:GreetingResources.resources

Zasoby w plikach resx

W przeciwieństwie do plików tekstowych, które mogą przechowywać tylko zasoby ciągów, pliki zasobów XML (resx) mogą przechowywać ciągi, dane binarne, takie jak obrazy, ikony i klipy audio oraz obiekty programowe. Plik resx zawiera standardowy nagłówek, który opisuje format wpisów zasobu i określa informacje o wersji pliku XML używanego do analizowania danych. Dane pliku zasobów są zgodne z nagłówkem XML. Każdy element danych składa się z pary nazwa/wartość, która jest zawarta w tagu data . Jego name atrybut definiuje nazwę zasobu, a zagnieżdżony value tag zawiera wartość zasobu. W przypadku danych value ciągu tag zawiera ciąg.

Na przykład następujący data tag definiuje zasób ciągu o nazwie prompt , którego wartość to "Wprowadź swoją nazwę:".

<data name="prompt" xml:space="preserve">
  <value>Enter your name:</value>
</data>

Ostrzeżenie

Nie używaj plików zasobów do przechowywania haseł, informacji poufnych zabezpieczeń ani danych prywatnych.

W przypadku obiektów zasobów tag danych zawiera type atrybut wskazujący typ danych zasobu. W przypadku obiektów, które składają się z danych binarnych, data tag zawiera mimetype również atrybut, który wskazuje base64 typ danych binarnych.

Uwaga

Wszystkie pliki resx używają binarnego formatowania serializacji do generowania i analizowania danych binarnych dla określonego typu. W związku z tym plik resx może stać się nieprawidłowy, jeśli format serializacji binarnej obiektu zmieni się w niezgodny sposób.

W poniższym przykładzie przedstawiono część pliku resx zawierającą Int32 zasób i obraz mapy bitowej.

<data name="i1" type="System.Int32, mscorlib">
  <value>20</value>
</data>

<data name="flag" type="System.Drawing.Bitmap, System.Drawing,
    Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
    mimetype="application/x-microsoft.net.object.bytearray.base64">
  <value>
    AAEAAAD/////AQAAAAAAAAAMAgAAADtTeX…
  </value>
</data>

Ważne

Ponieważ pliki resx muszą składać się z poprawnie sformułowanego kodu XML w wstępnie zdefiniowanym formacie, nie zalecamy ręcznej pracy z plikami resx, szczególnie gdy pliki resx zawierają zasoby inne niż ciągi. Zamiast tego program Visual Studio udostępnia przezroczysty interfejs do tworzenia plików resx i manipulowania nimi. Aby uzyskać więcej informacji, zobacz sekcję Pliki zasobów w programie Visual Studio . Można również programowo tworzyć pliki resx i manipulować nimi. Aby uzyskać więcej informacji, zobacz Programowe praca z plikami resx.

Zasoby w plikach resources

Za pomocą System.Resources.ResourceWriter klasy można programowo utworzyć plik zasobu binarnego (.resources) bezpośrednio z kodu. Możesz również użyć generatora plików zasobów (resgen.exe), aby utworzyć plik resources z pliku tekstowego lub pliku resx. Plik resources może zawierać dane binarne (tablice bajtów) i dane obiektów oprócz danych ciągów. Programowe tworzenie pliku resources wymaga następujących kroków:

  1. ResourceWriter Utwórz obiekt o unikatowej nazwie pliku. Można to zrobić, określając nazwę pliku lub strumień plików do konstruktora ResourceWriter klasy.

  2. Wywołaj jedno z przeciążeń ResourceWriter.AddResource metody dla każdego nazwanego zasobu, aby dodać go do pliku. Zasób może być ciągiem, obiektem lub kolekcją danych binarnych (tablicą bajtów).

  3. Wywołaj metodę , ResourceWriter.Close aby zapisać zasoby w pliku i zamknąć ResourceWriter obiekt.

Uwaga

Nie używaj plików zasobów do przechowywania haseł, informacji poufnych zabezpieczeń ani danych prywatnych.

Poniższy przykład programowo tworzy plik resources o nazwie CarResources.resources, który przechowuje sześć ciągów, ikonę i dwa obiekty zdefiniowane przez aplikację (dwa Automobile obiekty). Klasa Automobile , która jest zdefiniowana i utworzona w tym przykładzie, jest oznaczona atrybutem SerializableAttribute , co pozwala na utrwalone przez binarny formatator serializacji.

using System;
using System.Drawing;
using System.Resources;

[Serializable()] public class Automobile
{
   private string carMake;
   private string carModel;
   private int carYear;
   private int carDoors;
   private int carCylinders;

   public Automobile(string make, string model, int year) :
                     this(make, model, year, 0, 0)
   { }

   public Automobile(string make, string model, int year,
                     int doors, int cylinders)
   {
      this.carMake = make;
      this.carModel = model;
      this.carYear = year;
      this.carDoors = doors;
      this.carCylinders = cylinders;
   }

   public string Make {
      get { return this.carMake; }
   }

   public string Model {
      get { return this.carModel; }
   }

   public int Year {
      get { return this.carYear; }
   }

   public int Doors {
      get {
         return this.carDoors; }
   }

   public int Cylinders {
      get {
         return this.carCylinders; }
   }
}

public class Example
{
   public static void Main()
   {
      // Instantiate an Automobile object.
      Automobile car1 = new Automobile("Ford", "Model N", 1906, 0, 4);
      Automobile car2 = new Automobile("Ford", "Model T", 1909, 2, 4);
      // Define a resource file named CarResources.resx.
      using (ResourceWriter rw = new ResourceWriter(@".\CarResources.resources"))
      {
         rw.AddResource("Title", "Classic American Cars");
         rw.AddResource("HeaderString1", "Make");
         rw.AddResource("HeaderString2", "Model");
         rw.AddResource("HeaderString3", "Year");
         rw.AddResource("HeaderString4", "Doors");
         rw.AddResource("HeaderString5", "Cylinders");
         rw.AddResource("Information", SystemIcons.Information);
         rw.AddResource("EarlyAuto1", car1);
         rw.AddResource("EarlyAuto2", car2);
      }
   }
}
Imports System.Drawing
Imports System.Resources

<Serializable()> Public Class Automobile
    Private carMake As String
    Private carModel As String
    Private carYear As Integer
    Private carDoors AS Integer
    Private carCylinders As Integer

    Public Sub New(make As String, model As String, year As Integer)
        Me.New(make, model, year, 0, 0)
    End Sub

    Public Sub New(make As String, model As String, year As Integer,
                   doors As Integer, cylinders As Integer)
        Me.carMake = make
        Me.carModel = model
        Me.carYear = year
        Me.carDoors = doors
        Me.carCylinders = cylinders
    End Sub

    Public ReadOnly Property Make As String
        Get
            Return Me.carMake
        End Get
    End Property

    Public ReadOnly Property Model As String
        Get
            Return Me.carModel
        End Get
    End Property

    Public ReadOnly Property Year As Integer
        Get
            Return Me.carYear
        End Get
    End Property

    Public ReadOnly Property Doors As Integer
        Get
            Return Me.carDoors
        End Get
    End Property

    Public ReadOnly Property Cylinders As Integer
        Get
            Return Me.carCylinders
        End Get
    End Property
End Class

Module Example
    Public Sub Main()
        ' Instantiate an Automobile object.
        Dim car1 As New Automobile("Ford", "Model N", 1906, 0, 4)
        Dim car2 As New Automobile("Ford", "Model T", 1909, 2, 4)
        ' Define a resource file named CarResources.resx.
        Using rw As New ResourceWriter(".\CarResources.resources")
            rw.AddResource("Title", "Classic American Cars")
            rw.AddResource("HeaderString1", "Make")
            rw.AddResource("HeaderString2", "Model")
            rw.AddResource("HeaderString3", "Year")
            rw.AddResource("HeaderString4", "Doors")
            rw.AddResource("HeaderString5", "Cylinders")
            rw.AddResource("Information", SystemIcons.Information)
            rw.AddResource("EarlyAuto1", car1)
            rw.AddResource("EarlyAuto2", car2)
        End Using
    End Sub
End Module

Po utworzeniu pliku resources można go osadzić w pliku wykonywalnym lub bibliotece czasu wykonywania, dołączając przełącznik kompilatora /resource języka lub osadzając go w zestawie satelitarnym przy użyciu konsolidatora zestawów (Al.exe)..

Pliki zasobów w programie Visual Studio

Po dodaniu pliku zasobu do projektu programu Visual Studio program Visual Studio tworzy plik resx w katalogu projektu. Program Visual Studio udostępnia edytory zasobów, które umożliwiają dodawanie ciągów, obrazów i obiektów binarnych. Ponieważ edytory są przeznaczone tylko do obsługi danych statycznych, nie mogą być używane do przechowywania obiektów programowych; Dane obiektu należy zapisywać w pliku resx lub w pliku resources programowo. Aby uzyskać więcej informacji, zobacz Programowe działanie plików resx i sekcję Zasoby w plikach resources.

Jeśli dodasz zlokalizowane zasoby, nadaj im taką samą nazwę pliku głównego jak główny plik zasobu. Należy również wyznaczyć ich kulturę w nazwie pliku. Jeśli na przykład dodasz plik zasobów o nazwie Resources.resx, możesz również utworzyć pliki zasobów o nazwach Resources.en-US.resx i Resources.fr-FR.resx do przechowywania zlokalizowanych zasobów odpowiednio dla kultur angielskich (Stany Zjednoczone) i francuskich (Francja). Należy również wyznaczyć domyślną kulturę aplikacji. Jest to kultura, której zasoby są używane, jeśli nie można odnaleźć zlokalizowanych zasobów dla określonej kultury.

Aby określić kulturę domyślną, w Eksplorator rozwiązań w programie Visual Studio:

  • Otwórz właściwości projektu, kliknij prawym przyciskiem myszy projekt i wybierz polecenie Właściwości (lub Alt + Enter po wybraniu projektu).
  • Wybierz kartę Pakiet .
  • W obszarze Ogólne wybierz odpowiedni język/kulturę w kontrolce Języka neutralnego zestawu.
  • Zapisz zmiany.

W czasie kompilacji program Visual Studio najpierw konwertuje pliki resx w projekcie na pliki zasobów binarnych (.resources) i zapisuje je w podkatalogu katalogu obj projektu. Program Visual Studio osadza wszystkie pliki zasobów, które nie zawierają zlokalizowanych zasobów w głównym zestawie generowanym przez projekt. Jeśli jakiekolwiek pliki zasobów zawierają zlokalizowane zasoby, program Visual Studio osadza je w osobnych zestawach satelitarnych dla każdej zlokalizowanej kultury. Następnie przechowuje każdy zestaw satelitarny w katalogu, którego nazwa odpowiada zlokalizowanej kulturze. Na przykład zlokalizowane zasoby języka angielskiego (Stany Zjednoczone) są przechowywane w zestawie satelitarnym w podkatalogu en-US.

Zobacz też