Merge pull request #4223 from icsharpcode/fix/2744-resx-resource-writer

Fix ResXResourceWriter empty output and type names
This commit is contained in:
Siegfried Pammer
2026-10-08 20:57:31 +02:00
committed by GitHub
2 changed files with 70 additions and 9 deletions
@@ -46,6 +46,44 @@ namespace ICSharpCode.Decompiler.Tests.Util
const int TypeCodeStream = 33;
const int TypeCodeStartOfUserTypes = 0x40;
[Test]
public void ResXResourceWriter_DisposeWithoutResources_WritesEmptyFile()
{
string fileName = Path.Combine(TestContext.CurrentContext.WorkDirectory, Path.GetRandomFileName() + ".resx");
try
{
using (new ResXResourceWriter(fileName))
{
}
Assert.That(File.Exists(fileName), Is.True);
Assert.That(File.ReadAllText(fileName), Does.Contain("<resheader name=\"resmimetype\">"));
}
finally
{
File.Delete(fileName);
}
}
[Test]
public void ResXResourceWriter_UsesConfiguredAssemblyNames()
{
using var stream = new MemoryStream();
using (var writer = new ResXResourceWriter(stream))
{
writer.WinFormsAssemblyName = ", System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
writer.MSCorLibAssemblyName = ", mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
writer.AddResource("number", 1);
writer.AddResource("missing", (object?)null);
}
string resx = Encoding.UTF8.GetString(stream.ToArray());
Assert.That(resx, Does.Contain("System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0"));
Assert.That(resx, Does.Contain("System.Int32, mscorlib, Version=2.0.0.0"));
Assert.That(resx, Does.Contain("System.Resources.ResXNullRef, System.Windows.Forms, Version=2.0.0.0"));
Assert.That(resx, Does.Not.Contain("Version=4.0.0.0"));
}
[Test]
public void WellFormedFile_ReadsAllEntryKinds()
{
@@ -98,9 +98,32 @@ namespace ICSharpCode.Decompiler.Util
Dispose(false);
}
const string WinFormsAssemblyName = ", System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
const string MSCorLibAssemblyName = ", mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
const string ResXNullRefTypeName = "System.Resources.ResXNullRef" + WinFormsAssemblyName;
const string DefaultWinFormsAssemblyName = ", System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
const string DefaultMSCorLibAssemblyName = ", mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
string winFormsAssemblyName = DefaultWinFormsAssemblyName;
string msCorLibAssemblyName = DefaultMSCorLibAssemblyName;
public string WinFormsAssemblyName {
get => winFormsAssemblyName;
set {
ThrowIfWritingStarted();
winFormsAssemblyName = value ?? throw new ArgumentNullException(nameof(value));
}
}
public string MSCorLibAssemblyName {
get => msCorLibAssemblyName;
set {
ThrowIfWritingStarted();
msCorLibAssemblyName = value ?? throw new ArgumentNullException(nameof(value));
}
}
void ThrowIfWritingStarted()
{
if (writer != null || written)
throw new InvalidOperationException("Assembly names cannot be changed after writing started.");
}
void InitWriter()
{
@@ -222,7 +245,7 @@ namespace ICSharpCode.Decompiler.Util
{
case null:
// nulls written as ResXNullRef
WriteString(name, "", ResXNullRefTypeName, comment);
WriteString(name, "", "System.Resources.ResXNullRef" + WinFormsAssemblyName, comment);
break;
case string s:
WriteString(name, s, null, comment);
@@ -295,13 +318,13 @@ namespace ICSharpCode.Decompiler.Util
public void Close()
{
if (!written)
{
Generate();
}
if (writer != null)
{
if (!written)
{
Generate();
}
writer.Close();
stream = null;
filename = null;