Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Nota
Artikel ini berlaku untuk .NET Framework. Untuk informasi yang berlaku untuk .NET 5+ (termasuk .NET Core), lihat Sumber daya dalam file .resx.
Karena file sumber daya XML (.resx) harus terdiri dari XML yang terdefinisi dengan baik, termasuk header yang harus mengikuti skema tertentu diikuti oleh data dalam pasangan nama/nilai, Anda mungkin menemukan bahwa membuat file ini secara manual rawan kesalahan. Sebagai alternatif, Anda dapat membuat file .resx secara terprogram dengan menggunakan jenis dan anggota di Pustaka Kelas .NET. Anda juga dapat menggunakan Pustaka Kelas .NET untuk mengambil sumber daya yang disimpan dalam file .resx. Artikel ini menjelaskan cara menggunakan jenis dan anggota di ruang nama System.Resources untuk bekerja dengan file .resx.
Artikel ini membahas bekerja dengan file XML (.resx) yang berisi sumber daya. Untuk informasi tentang bekerja dengan file sumber daya biner yang telah disematkan dalam rakitan, lihat ResourceManager.
Peringatan
Ada juga cara untuk bekerja dengan file .resx selain secara terprogram. Saat Anda menambahkan file sumber daya ke proyek Visual Studio , Visual Studio menyediakan antarmuka untuk membuat dan memelihara file .resx, dan secara otomatis mengonversi file .resx ke file .resources pada waktu kompilasi. Anda juga dapat menggunakan editor teks untuk memanipulasi file .resx secara langsung. Namun, untuk menghindari kerusakan file, berhati-hatilah untuk tidak memodifikasi informasi biner apa pun yang disimpan dalam file.
Membuat file .resx
Anda dapat menggunakan System.Resources.ResXResourceWriter kelas untuk membuat file .resx secara terprogram, dengan mengikuti langkah-langkah berikut:
Buat instans ResXResourceWriter objek dengan memanggil ResXResourceWriter(String) metode dan memberikan nama file .resx. Nama file harus menyertakan ekstensi .resx. Jika Anda membuat instans objek ResXResourceWriter dalam blok
using, Anda tidak perlu secara eksplisit memanggil metode ResXResourceWriter.Close di langkah 3.ResXResourceWriter.AddResource Panggil metode untuk setiap sumber daya yang ingin Anda tambahkan ke file. Gunakan kelebihan beban metode ini untuk menambahkan data string, objek, dan biner (byte array). Jika sumber daya adalah objek, sumber daya harus dapat diserialisasikan.
ResXResourceWriter.Close Panggil metode untuk menghasilkan file sumber daya dan untuk merilis semua sumber daya. Jika objek ResXResourceWriter dibuat dalam blok
using, sumber daya dituliskan ke berkas .resx dan sumber daya yang digunakan oleh objek ResXResourceWriter dilepaskan di akhir blokusing.
File .resx yang dihasilkan memiliki header yang sesuai dan tag data untuk setiap sumber daya yang ditambahkan oleh metode ResXResourceWriter.AddResource.
Peringatan
Jangan gunakan file sumber daya untuk menyimpan kata sandi, informasi yang sensitif keamanan, atau data privat.
Contoh berikut membuat file .resx bernama CarResources.resx yang menyimpan enam string, ikon, dan dua objek yang ditentukan aplikasi (dua Automobile objek). Kelas Automobile , yang didefinisikan dan dibuat dalam contoh, ditandai dengan SerializableAttribute atribut .
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 (ResXResourceWriter resx = new ResXResourceWriter(@".\CarResources.resx"))
{
resx.AddResource("Title", "Classic American Cars");
resx.AddResource("HeaderString1", "Make");
resx.AddResource("HeaderString2", "Model");
resx.AddResource("HeaderString3", "Year");
resx.AddResource("HeaderString4", "Doors");
resx.AddResource("HeaderString5", "Cylinders");
resx.AddResource("Information", SystemIcons.Information);
resx.AddResource("EarlyAuto1", car1);
resx.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 resx As New ResXResourceWriter(".\CarResources.resx")
resx.AddResource("Title", "Classic American Cars")
resx.AddResource("HeaderString1", "Make")
resx.AddResource("HeaderString2", "Model")
resx.AddResource("HeaderString3", "Year")
resx.AddResource("HeaderString4", "Doors")
resx.AddResource("HeaderString5", "Cylinders")
resx.AddResource("Information", SystemIcons.Information)
resx.AddResource("EarlyAuto1", car1)
resx.AddResource("EarlyAuto2", car2)
End Using
End Sub
End Module
Petunjuk / Saran
Anda juga dapat menggunakan Visual Studio untuk membuat file .resx. Pada waktu kompilasi, Visual Studio menggunakan Resource File Generator (Resgen.exe) untuk mengonversi file .resx ke file sumber daya biner (.resources), dan juga menyematkannya di rakitan aplikasi atau rakitan satelit.
Anda tidak dapat menyematkan file .resx dalam eksekusi runtime atau mengompilasinya ke dalam rakitan satelit. Anda harus mengonversi file .resx Anda menjadi file sumber daya biner (.resources) dengan menggunakan Resource File Generator (Resgen.exe). File .resources yang dihasilkan kemudian dapat disematkan dalam rakitan aplikasi atau rakitan satelit. Untuk informasi selengkapnya, lihat Membuat file sumber daya.
Menghitung sumber daya
Dalam beberapa kasus, Anda mungkin ingin mengambil semua sumber daya, bukan sumber daya tertentu, dari file .resx. Untuk melakukan ini, Anda dapat menggunakan System.Resources.ResXResourceReader kelas , yang menyediakan enumerator untuk semua sumber daya dalam file .resx. Kelas System.Resources.ResXResourceReader mengimplementasikan IDictionaryEnumerator, yang mengembalikan DictionaryEntry objek yang mewakili sumber daya tertentu untuk setiap iterasi perulangan. Propertinya DictionaryEntry.Key mengembalikan kunci sumber daya, dan propertinya DictionaryEntry.Value mengembalikan nilai sumber daya.
Contoh berikut membuat ResXResourceReader objek untuk file CarResources.resx yang dibuat dalam contoh sebelumnya dan melakukan iterasi melalui file sumber daya. Ini menambahkan dua Automobile objek yang ditentukan dalam file sumber daya ke System.Collections.Generic.List<T> objek, dan menambahkan lima dari enam string ke SortedList objek. Nilai-nilai dalam objek SortedList dikonversi menjadi array parameter, yang digunakan untuk menampilkan judul kolom ke konsol. Nilai Automobile properti juga ditampilkan pada konsol.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Resources;
public class Example
{
public static void Main()
{
string resxFile = @".\CarResources.resx";
List<Automobile> autos = new List<Automobile>();
SortedList headers = new SortedList();
using (ResXResourceReader resxReader = new ResXResourceReader(resxFile))
{
foreach (DictionaryEntry entry in resxReader) {
if (((string) entry.Key).StartsWith("EarlyAuto"))
autos.Add((Automobile) entry.Value);
else if (((string) entry.Key).StartsWith("Header"))
headers.Add((string) entry.Key, (string) entry.Value);
}
}
string[] headerColumns = new string[headers.Count];
headers.GetValueList().CopyTo(headerColumns, 0);
Console.WriteLine("{0,-8} {1,-10} {2,-4} {3,-5} {4,-9}\n",
headerColumns);
foreach (var auto in autos)
Console.WriteLine("{0,-8} {1,-10} {2,4} {3,5} {4,9}",
auto.Make, auto.Model, auto.Year,
auto.Doors, auto.Cylinders);
}
}
// The example displays the following output:
// Make Model Year Doors Cylinders
//
// Ford Model N 1906 0 4
// Ford Model T 1909 2 4
Imports System.Collections
Imports System.Collections.Generic
Imports System.Resources
Module Example
Public Sub Main()
Dim resxFile As String = ".\CarResources.resx"
Dim autos As New List(Of Automobile)
Dim headers As New SortedList()
Using resxReader As New ResXResourceReader(resxFile)
For Each entry As DictionaryEntry In resxReader
If CType(entry.Key, String).StartsWith("EarlyAuto") Then
autos.Add(CType(entry.Value, Automobile))
Else If CType(entry.Key, String).StartsWith("Header") Then
headers.Add(CType(entry.Key, String), CType(entry.Value, String))
End If
Next
End Using
Dim headerColumns(headers.Count - 1) As String
headers.GetValueList().CopyTo(headerColumns, 0)
Console.WriteLine("{0,-8} {1,-10} {2,-4} {3,-5} {4,-9}",
headerColumns)
Console.WriteLine()
For Each auto In autos
Console.WriteLine("{0,-8} {1,-10} {2,4} {3,5} {4,9}",
auto.Make, auto.Model, auto.Year,
auto.Doors, auto.Cylinders)
Next
End Sub
End Module
' The example displays the following output:
' Make Model Year Doors Cylinders
'
' Ford Model N 1906 0 4
' Ford Model T 1909 2 4
Mengambil sumber daya tertentu
Selain menghitung item dalam file .resx, Anda dapat mengambil sumber daya tertentu berdasarkan nama dengan menggunakan System.Resources.ResXResourceSet kelas . Metode ResourceSet.GetString(String) mengambil nilai dari sumber daya bertipe string yang ditentukan. Metode ini ResourceSet.GetObject(String) mengambil kembali nilai dari objek yang bernama atau data biner. Metode mengembalikan objek yang kemudian harus di-casting (dalam C#) atau dikonversi (di Visual Basic) ke objek dengan tipe yang sesuai.
Contoh berikut mengambil teks judul dan ikon formulir berdasarkan nama sumber daya mereka. Ini juga mengambil objek yang didefinisikan oleh aplikasi yang digunakan dalam contoh sebelumnya dan menampilkannya dalam kontrol Automobile.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Resources;
using System.Windows.Forms;
public class CarDisplayApp : Form
{
private const string resxFile = @".\CarResources.resx";
Automobile[] cars;
public static void Main()
{
CarDisplayApp app = new CarDisplayApp();
Application.Run(app);
}
public CarDisplayApp()
{
// Instantiate controls.
PictureBox pictureBox = new PictureBox();
pictureBox.Location = new Point(10, 10);
this.Controls.Add(pictureBox);
DataGridView grid = new DataGridView();
grid.Location = new Point(10, 60);
this.Controls.Add(grid);
// Get resources from .resx file.
using (ResXResourceSet resxSet = new ResXResourceSet(resxFile))
{
// Retrieve the string resource for the title.
this.Text = resxSet.GetString("Title");
// Retrieve the image.
Icon image = (Icon) resxSet.GetObject("Information", true);
if (image != null)
pictureBox.Image = image.ToBitmap();
// Retrieve Automobile objects.
List<Automobile> carList = new List<Automobile>();
string resName = "EarlyAuto";
Automobile auto;
int ctr = 1;
do {
auto = (Automobile) resxSet.GetObject(resName + ctr.ToString());
ctr++;
if (auto != null)
carList.Add(auto);
} while (auto != null);
cars = carList.ToArray();
grid.DataSource = cars;
}
}
}
Imports System.Collections.Generic
Imports System.Drawing
Imports System.Resources
Imports System.Windows.Forms
Public Class CarDisplayApp : Inherits Form
Private Const resxFile As String = ".\CarResources.resx"
Dim cars() As Automobile
Public Shared Sub Main()
Dim app As New CarDisplayApp()
Application.Run(app)
End Sub
Public Sub New()
' Instantiate controls.
Dim pictureBox As New PictureBox()
pictureBox.Location = New Point(10, 10)
Me.Controls.Add(pictureBox)
Dim grid As New DataGridView()
grid.Location = New Point(10, 60)
Me.Controls.Add(grid)
' Get resources from .resx file.
Using resxSet As New ResXResourceSet(resxFile)
' Retrieve the string resource for the title.
Me.Text = resxSet.GetString("Title")
' Retrieve the image.
Dim image As Icon = CType(resxSet.GetObject("Information", True), Icon)
If image IsNot Nothing Then
pictureBox.Image = image.ToBitmap()
End If
' Retrieve Automobile objects.
Dim carList As New List(Of Automobile)
Dim resName As String = "EarlyAuto"
Dim auto As Automobile
Dim ctr As Integer = 1
Do
auto = CType(resxSet.GetObject(resName + ctr.ToString()), Automobile)
ctr += 1
If auto IsNot Nothing Then carList.Add(auto)
Loop While auto IsNot Nothing
cars = carList.ToArray()
grid.DataSource = cars
End Using
End Sub
End Class
Mengonversi file .resx ke file .resources biner
Mengonversi file .resx menjadi file sumber daya biner (.resources) yang disematkan memiliki keuntungan signifikan. Meskipun file .resx mudah dibaca dan dikelola selama pengembangan aplikasi, file tersebut jarang disertakan dengan aplikasi yang sudah selesai. Jika didistribusikan dengan aplikasi, mereka ada sebagai file terpisah selain dari aplikasi yang dapat dieksekusi dan pustaka yang menyertainya. Sebaliknya, file .resources disematkan dalam aplikasi yang dapat dieksekusi atau rakitan yang menyertainya. Selain itu, untuk aplikasi yang dilokalkan, mengandalkan file .resx pada runtime menempatkan tanggung jawab untuk menangani fallback sumber daya pada pengembang. Sebaliknya, jika sekumpulan ansambel satelit yang berisi file bersifat .resources yang disematkan telah dibuat, runtime bahasa umum .NET menangani proses fallback sumber daya.
Untuk mengonversi file .resx ke file .resources , Anda menggunakan Resource File Generator (resgen.exe), yang memiliki sintaks dasar berikut:
resgen.exe .resxFilename
Hasilnya adalah file sumber daya biner yang memiliki nama file akar yang sama dengan file .resx dan ekstensi file .resources. File ini kemudian dapat dikompilasi ke dalam executable atau pustaka pada waktu kompilasi. Jika Anda menggunakan pengkompilasi Visual Basic, gunakan sintaks berikut untuk menyematkan file .resources dalam aplikasi yang dapat dieksekusi:
vbc filename .vb -resource: .resourcesFilename
Jika Anda menggunakan C#, sintaksnya adalah sebagai berikut:
csc filename .cs -resource: .resourcesFilename
File .resources juga dapat disematkan dalam rakitan satelit dengan menggunakan Assembly Linker (al.exe), yang memiliki sintaks dasar berikut:
al resourcesFilename -out: assemblyFilename