Browse Source

#1225: Fix inconsistencies in path handling when decompiling resources.

Also, move the .resources->.resx conversion into the base class.
Now that we have our own ResXWriter implementation, there's no longer any reason to keep this specific to ILSpy.
pull/1243/head
Daniel Grunwald 7 years ago
parent
commit
f8efc7cf57
  1. 22
      ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs
  2. 8
      ICSharpCode.Decompiler/Util/ResXResourceWriter.cs
  3. 14
      ILSpy/Languages/CSharpLanguage.cs

22
ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs

@ -373,7 +373,7 @@ namespace ICSharpCode.Decompiler.CSharp
Stream entryStream = (Stream)value; Stream entryStream = (Stream)value;
entryStream.Position = 0; entryStream.Position = 0;
individualResources.AddRange( individualResources.AddRange(
WriteResourceToFile(Path.Combine(targetDirectory, fileName), (string)name, entryStream)); WriteResourceToFile(fileName, (string)name, entryStream));
} }
decodedIntoIndividualFiles = true; decodedIntoIndividualFiles = true;
} else { } else {
@ -388,7 +388,7 @@ namespace ICSharpCode.Decompiler.CSharp
} }
} else { } else {
stream.Position = 0; stream.Position = 0;
string fileName = Path.ChangeExtension(GetFileNameForResource(r.Name), ".resource"); string fileName = GetFileNameForResource(r.Name);
foreach (var entry in WriteResourceToFile(fileName, r.Name, stream)) { foreach (var entry in WriteResourceToFile(fileName, r.Name, stream)) {
yield return entry; yield return entry;
} }
@ -406,10 +406,24 @@ namespace ICSharpCode.Decompiler.CSharp
protected virtual IEnumerable<Tuple<string, string>> WriteResourceToFile(string fileName, string resourceName, Stream entryStream) protected virtual IEnumerable<Tuple<string, string>> WriteResourceToFile(string fileName, string resourceName, Stream entryStream)
{ {
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) { if (fileName.EndsWith(".resources", StringComparison.OrdinalIgnoreCase)) {
string resx = Path.ChangeExtension(fileName, ".resx");
try {
using (FileStream fs = new FileStream(Path.Combine(targetDirectory, resx), FileMode.Create, FileAccess.Write))
using (ResXResourceWriter writer = new ResXResourceWriter(fs)) {
foreach (var entry in new ResourcesFile(entryStream)) {
writer.AddResource(entry.Key, entry.Value);
}
}
return new[] { Tuple.Create("EmbeddedResource", resx) };
} catch (BadImageFormatException) {
// if the .resources can't be decoded, just save them as-is
}
}
using (FileStream fs = new FileStream(Path.Combine(targetDirectory, fileName), FileMode.Create, FileAccess.Write)) {
entryStream.CopyTo(fs); entryStream.CopyTo(fs);
} }
yield return Tuple.Create("EmbeddedResource", fileName); return new[] { Tuple.Create("EmbeddedResource", fileName) };
} }
string GetFileNameForResource(string fullName) string GetFileNameForResource(string fullName)

8
ICSharpCode.Decompiler/Util/ResXResourceWriter.cs

@ -466,11 +466,11 @@ namespace ICSharpCode.Decompiler.Util
public void Close() public void Close()
{ {
if (!written) {
Generate();
}
if (writer != null) { if (writer != null) {
if (!written) {
Generate();
}
writer.Close(); writer.Close();
stream = null; stream = null;
filename = null; filename = null;

14
ILSpy/Languages/CSharpLanguage.cs

@ -392,20 +392,12 @@ namespace ICSharpCode.ILSpy
protected override IEnumerable<Tuple<string, string>> WriteResourceToFile(string fileName, string resourceName, Stream entryStream) protected override IEnumerable<Tuple<string, string>> WriteResourceToFile(string fileName, string resourceName, Stream entryStream)
{ {
if (fileName.EndsWith(".resource", StringComparison.OrdinalIgnoreCase)) {
fileName = Path.ChangeExtension(fileName, ".resx");
using (FileStream fs = new FileStream(Path.Combine(targetDirectory, fileName), FileMode.Create, FileAccess.Write))
using (ResXResourceWriter writer = new ResXResourceWriter(fs)) {
foreach (var entry in new ResourcesFile(entryStream)) {
writer.AddResource(entry.Key, entry.Value);
}
}
return new[] { Tuple.Create("EmbeddedResource", fileName) };
}
foreach (var handler in App.ExportProvider.GetExportedValues<IResourceFileHandler>()) { foreach (var handler in App.ExportProvider.GetExportedValues<IResourceFileHandler>()) {
if (handler.CanHandle(fileName, options)) { if (handler.CanHandle(fileName, options)) {
entryStream.Position = 0; entryStream.Position = 0;
return new[] { Tuple.Create(handler.EntryType, handler.WriteResourceToFile(assembly, fileName, entryStream, options)) }; fileName = Path.Combine(targetDirectory, fileName);
fileName = handler.WriteResourceToFile(assembly, fileName, entryStream, options);
return new[] { Tuple.Create(handler.EntryType, fileName) };
} }
} }
return base.WriteResourceToFile(fileName, resourceName, entryStream); return base.WriteResourceToFile(fileName, resourceName, entryStream);

Loading…
Cancel
Save