Browse Source

Merge pull request #2567 from icsharpcode/filename-sanitizer

Improve file name sanitizer
pull/2700/head
Siegfried Pammer 4 years ago committed by GitHub
parent
commit
0f3e8b79be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      ICSharpCode.Decompiler.Tests/TestCases/PdbGen/ForLoopTests.xml
  2. 2
      ICSharpCode.Decompiler.Tests/TestCases/PdbGen/HelloWorld.xml
  3. 2
      ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LambdaCapturing.xml
  4. 78
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs
  5. 5
      ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs
  6. 21
      ICSharpCode.Decompiler/DecompilerSettings.cs
  7. 5
      ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs
  8. 3
      ILSpy/Commands/GeneratePdbContextMenuEntry.cs
  9. 4
      ILSpy/Commands/SelectPdbContextMenuEntry.cs
  10. 12
      ILSpy/Options/MiscSettingsPanel.xaml
  11. 4
      ILSpy/Options/MiscSettingsPanel.xaml.cs
  12. 26
      ILSpy/Properties/Resources.Designer.cs
  13. 14
      ILSpy/Properties/Resources.resx
  14. 10
      ILSpy/TextView/DecompilerTextView.cs
  15. 4
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  16. 4
      ILSpy/TreeNodes/ResourceNodes/ResourceEntryNode.cs
  17. 5
      ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs
  18. 3
      ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs

2
ICSharpCode.Decompiler.Tests/TestCases/PdbGen/ForLoopTests.xml

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<symbols>
<files>
<file id="1" name="ICSharpCode\Decompiler\Tests\TestCases\PdbGen\ForLoopTests.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System;
<file id="1" name="ICSharpCode.Decompiler.Tests.TestCases.PdbGen\ForLoopTests.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;

2
ICSharpCode.Decompiler.Tests/TestCases/PdbGen/HelloWorld.xml

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<symbols>
<files>
<file id="1" name="ICSharpCode\Decompiler\Tests\TestCases\PdbGen\HelloWorld.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System;
<file id="1" name="ICSharpCode.Decompiler.Tests.TestCases.PdbGen\HelloWorld.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;

2
ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LambdaCapturing.xml

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<symbols>
<files>
<file id="1" name="ICSharpCode\Decompiler\Tests\TestCases\PdbGen\LambdaCapturing.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System;
<file id="1" name="ICSharpCode.Decompiler.Tests.TestCases.PdbGen\LambdaCapturing.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;

78
ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs

@ -214,7 +214,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -214,7 +214,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}
else
{
string dir = CleanUpDirectoryName(ns);
string dir = Settings.UseNestedDirectoriesForNamespaces ? CleanUpPath(ns) : CleanUpDirectoryName(ns);
if (directories.Add(dir))
Directory.CreateDirectory(Path.Combine(TargetDirectory, dir));
return Path.Combine(dir, file);
@ -269,7 +269,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -269,7 +269,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
{
foreach (var (name, value) in resourcesFile)
{
string fileName = CleanUpFileName(name)
string fileName = SanitizeFileName(name)
.Replace('/', Path.DirectorySeparatorChar);
string dirName = Path.GetDirectoryName(fileName);
if (!string.IsNullOrEmpty(dirName) && directories.Add(dirName))
@ -279,7 +279,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -279,7 +279,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
Stream entryStream = (Stream)value;
entryStream.Position = 0;
individualResources.AddRange(
WriteResourceToFile(fileName, (string)name, entryStream));
WriteResourceToFile(fileName, name, entryStream));
}
decodedIntoIndividualFiles = true;
}
@ -368,6 +368,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -368,6 +368,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
// That is, a full name of the form "Namespace1.Namespace2{...}.NamespaceN.ResourceName" is split such that
// the directory part Namespace1\Namespace2\... reuses as many existing directories as
// possible, and only the remaining name parts are used as prefix for the filename.
// This is not affected by the UseNestedDirectoriesForNamespaces setting.
string[] splitName = fullName.Split(Path.DirectorySeparatorChar);
string fileName = string.Join(".", splitName);
string separator = Path.DirectorySeparatorChar.ToString();
@ -546,7 +547,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -546,7 +547,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
{
case PlatformID.MacOSX:
case PlatformID.Unix:
return (true, int.MaxValue, int.MaxValue);
return (true, int.MaxValue, 255);
case PlatformID.Win32NT:
const string key = @"SYSTEM\CurrentControlSet\Control\FileSystem";
var fileSystem = Registry.LocalMachine.OpenSubKey(key);
@ -571,14 +572,25 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -571,14 +572,25 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
/// </summary>
public static string CleanUpFileName(string text)
{
return CleanUpFileName(text, separateAtDots: false);
return CleanUpName(text, separateAtDots: false, treatAsFileName: false);
}
/// <summary>
/// Removes invalid characters from file names and reduces their length,
/// but keeps file extensions and path structure intact.
/// </summary>
public static string SanitizeFileName(string fileName)
{
return CleanUpName(fileName, separateAtDots: false, treatAsFileName: true);
}
/// <summary>
/// Cleans up a node name for use as a file system name. If <paramref name="separateAtDots"/> is active,
/// dots are seen as segment separators. Each segment is limited to 255 characters.
/// dots are seen as segment separators. Each segment is limited to maxSegmentLength characters.
/// (see <see cref="GetLongPathSupport"/>) If <paramref name="treatAsFileName"/> is active,
/// we check for file a extension and try to preserve it, if it's valid.
/// </summary>
static string CleanUpFileName(string text, bool separateAtDots)
static string CleanUpName(string text, bool separateAtDots, bool treatAsFileName)
{
int pos = text.IndexOf(':');
if (pos > 0)
@ -587,23 +599,49 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -587,23 +599,49 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
if (pos > 0)
text = text.Substring(0, pos);
text = text.Trim();
// Whitelist allowed characters, replace everything else:
StringBuilder b = new StringBuilder(text.Length);
string extension = null;
int currentSegmentLength = 0;
var (supportsLongPaths, maxPathLength, maxSegmentLength) = longPathSupport.Value;
if (treatAsFileName)
{
// Check if input is a file name, i.e., has a valid extension
// If yes, preserve extension and append it at the end.
// But only, if the extension length does not exceed maxSegmentLength,
// if that's the case we just give up and treat the extension no different
// from the file name.
int lastDot = text.LastIndexOf('.');
if (lastDot >= 0 && text.Length - lastDot < maxSegmentLength)
{
string originalText = text;
extension = text.Substring(lastDot);
text = text.Remove(lastDot);
foreach (var c in extension)
{
if (!(char.IsLetterOrDigit(c) || c == '-' || c == '_' || c == '.'))
{
// extension contains an invalid character, therefore cannot be a valid extension.
extension = null;
text = originalText;
break;
}
}
}
}
// Whitelist allowed characters, replace everything else:
StringBuilder b = new StringBuilder(text.Length + (extension?.Length ?? 0));
foreach (var c in text)
{
currentSegmentLength++;
if (char.IsLetterOrDigit(c) || c == '-' || c == '_')
{
// if the current segment exceeds 255 characters,
// if the current segment exceeds maxSegmentLength characters,
// skip until the end of the segment.
if (currentSegmentLength <= maxSegmentLength)
b.Append(c);
}
else if (c == '.' && b.Length > 0 && b[b.Length - 1] != '.')
{
// if the current segment exceeds 255 characters,
// if the current segment exceeds maxSegmentLength characters,
// skip until the end of the segment.
if (separateAtDots || currentSegmentLength <= maxSegmentLength)
b.Append('.'); // allow dot, but never two in a row
@ -612,9 +650,15 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -612,9 +650,15 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
if (separateAtDots)
currentSegmentLength = 0;
}
else if (treatAsFileName && (c == '/' || c == '\\') && currentSegmentLength > 0)
{
// if we treat this as a file name, we've started a new segment
b.Append(c);
currentSegmentLength = 0;
}
else
{
// if the current segment exceeds 255 characters,
// if the current segment exceeds maxSegmentLength characters,
// skip until the end of the segment.
if (currentSegmentLength <= maxSegmentLength)
b.Append('-');
@ -625,6 +669,8 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -625,6 +669,8 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
if (b.Length == 0)
b.Append('-');
string name = b.ToString();
if (extension != null)
name += extension;
if (IsReservedFileSystemName(name))
return name + "_";
else if (name == ".")
@ -638,7 +684,13 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -638,7 +684,13 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
/// </summary>
public static string CleanUpDirectoryName(string text)
{
return CleanUpFileName(text, separateAtDots: true).Replace('.', Path.DirectorySeparatorChar);
return CleanUpName(text, separateAtDots: false, treatAsFileName: false);
}
public static string CleanUpPath(string text)
{
return CleanUpName(text, separateAtDots: true, treatAsFileName: false)
.Replace('.', Path.DirectorySeparatorChar);
}
static bool IsReservedFileSystemName(string name)

5
ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

@ -66,7 +66,10 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -66,7 +66,10 @@ namespace ICSharpCode.Decompiler.DebugInfo
string BuildFileNameFromTypeName(TypeDefinitionHandle handle)
{
var typeName = handle.GetFullTypeName(reader).TopLevelTypeName;
return Path.Combine(WholeProjectDecompiler.CleanUpDirectoryName(typeName.Namespace), WholeProjectDecompiler.CleanUpFileName(typeName.Name) + ".cs");
string ns = settings.UseNestedDirectoriesForNamespaces
? WholeProjectDecompiler.CleanUpPath(typeName.Namespace)
: WholeProjectDecompiler.CleanUpDirectoryName(typeName.Namespace);
return Path.Combine(ns, WholeProjectDecompiler.CleanUpFileName(typeName.Name) + ".cs");
}
foreach (var sourceFile in reader.GetTopLevelTypeDefinitions().GroupBy(BuildFileNameFromTypeName))

21
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -1777,7 +1777,7 @@ namespace ICSharpCode.Decompiler @@ -1777,7 +1777,7 @@ namespace ICSharpCode.Decompiler
/// Gets or sets a value indicating whether the new SDK style format
/// shall be used for the generated project files.
/// </summary>
[Category("DecompilerSettings.Other")]
[Category("DecompilerSettings.ProjectExport")]
[Description("DecompilerSettings.UseSdkStyleProjectFormat")]
public bool UseSdkStyleProjectFormat {
get { return useSdkStyleProjectFormat; }
@ -1790,6 +1790,25 @@ namespace ICSharpCode.Decompiler @@ -1790,6 +1790,25 @@ namespace ICSharpCode.Decompiler
}
}
bool useNestedDirectoriesForNamespaces;
/// <summary>
/// Gets/sets whether namespaces and namespace-like identifiers should be split at '.'
/// and each part should produce a new level of nesting in the output directory structure.
/// </summary>
[Category("DecompilerSettings.ProjectExport")]
[Description("DecompilerSettings.UseNestedDirectoriesForNamespaces")]
public bool UseNestedDirectoriesForNamespaces {
get { return useNestedDirectoriesForNamespaces; }
set {
if (useNestedDirectoriesForNamespaces != value)
{
useNestedDirectoriesForNamespaces = value;
OnPropertyChanged();
}
}
}
bool aggressiveScalarReplacementOfAggregates = false;
[Category("DecompilerSettings.Other")]

5
ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs

@ -23,6 +23,7 @@ using System.Linq; @@ -23,6 +23,7 @@ using System.Linq;
using System.Threading.Tasks;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
@ -46,7 +47,7 @@ namespace ICSharpCode.ILSpy @@ -46,7 +47,7 @@ namespace ICSharpCode.ILSpy
return;
var assembly = selectedNodes[0].PackageEntry;
SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = Path.GetFileName(DecompilerTextView.CleanUpName(assembly.Name));
dlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(assembly.Name));
dlg.Filter = ".NET assemblies|*.dll;*.exe;*.winmd" + Resources.AllFiles;
dlg.InitialDirectory = Path.GetDirectoryName(bundleNode.LoadedAssembly.FileName);
if (dlg.ShowDialog() != true)
@ -70,7 +71,7 @@ namespace ICSharpCode.ILSpy @@ -70,7 +71,7 @@ namespace ICSharpCode.ILSpy
{
foreach (var node in selectedNodes)
{
var fileName = Path.GetFileName(DecompilerTextView.CleanUpName(node.PackageEntry.Name));
var fileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(node.PackageEntry.Name));
SaveEntry(output, node.PackageEntry, Path.Combine(outputFolderOrFileName, fileName));
}
}

3
ILSpy/Commands/GeneratePdbContextMenuEntry.cs

@ -25,6 +25,7 @@ using System.Windows; @@ -25,6 +25,7 @@ using System.Windows;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
@ -63,7 +64,7 @@ namespace ICSharpCode.ILSpy @@ -63,7 +64,7 @@ namespace ICSharpCode.ILSpy
return;
}
SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = DecompilerTextView.CleanUpName(assembly.ShortName) + ".pdb";
dlg.FileName = WholeProjectDecompiler.CleanUpFileName(assembly.ShortName) + ".pdb";
dlg.Filter = Resources.PortablePDBPdbAllFiles;
dlg.InitialDirectory = Path.GetDirectoryName(assembly.FileName);
if (dlg.ShowDialog() != true)

4
ILSpy/Commands/SelectPdbContextMenuEntry.cs

@ -19,8 +19,8 @@ @@ -19,8 +19,8 @@
using System.IO;
using System.Linq;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using Microsoft.Win32;
@ -35,7 +35,7 @@ namespace ICSharpCode.ILSpy @@ -35,7 +35,7 @@ namespace ICSharpCode.ILSpy
if (assembly == null)
return;
OpenFileDialog dlg = new OpenFileDialog();
dlg.FileName = DecompilerTextView.CleanUpName(assembly.ShortName) + ".pdb";
dlg.FileName = WholeProjectDecompiler.CleanUpFileName(assembly.ShortName) + ".pdb";
dlg.Filter = Resources.PortablePDBPdbAllFiles;
dlg.InitialDirectory = Path.GetDirectoryName(assembly.FileName);
if (dlg.ShowDialog() != true)

12
ILSpy/Options/MiscSettingsPanel.xaml

@ -6,9 +6,13 @@ @@ -6,9 +6,13 @@
xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Margin="10">
<CheckBox IsChecked="{Binding AllowMultipleInstances}" Content="{x:Static properties:Resources.AllowMultipleInstances}" />
<CheckBox IsChecked="{Binding LoadPreviousAssemblies}" Content="{x:Static properties:Resources.LoadAssembliesThatWereLoadedInTheLastInstance}"/>
<Button Command="{Binding AddRemoveShellIntegrationCommand}" Content="{Binding AddRemoveShellIntegrationText}" Margin="3" />
<StackPanel Orientation="Vertical">
<GroupBox Header="{x:Static properties:Resources.Misc}">
<StackPanel Margin="10">
<CheckBox IsChecked="{Binding AllowMultipleInstances}" Content="{x:Static properties:Resources.AllowMultipleInstances}" />
<CheckBox IsChecked="{Binding LoadPreviousAssemblies}" Content="{x:Static properties:Resources.LoadAssembliesThatWereLoadedInTheLastInstance}"/>
<Button Command="{Binding AddRemoveShellIntegrationCommand}" Content="{Binding AddRemoveShellIntegrationText}" Margin="3" />
</StackPanel>
</GroupBox>
</StackPanel>
</UserControl>

4
ILSpy/Options/MiscSettingsPanel.xaml.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy.Options @@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy.Options
{
XElement e = settings["MiscSettings"];
var s = new MiscSettings();
s.AllowMultipleInstances = (bool?)e.Attribute("AllowMultipleInstances") ?? false;
s.AllowMultipleInstances = (bool?)e.Attribute(nameof(s.AllowMultipleInstances)) ?? false;
s.LoadPreviousAssemblies = (bool?)e.Attribute(nameof(s.LoadPreviousAssemblies)) ?? true;
return s;
@ -60,7 +60,7 @@ namespace ICSharpCode.ILSpy.Options @@ -60,7 +60,7 @@ namespace ICSharpCode.ILSpy.Options
var s = (MiscSettings)this.DataContext;
var section = new XElement("MiscSettings");
section.SetAttributeValue("AllowMultipleInstances", s.AllowMultipleInstances);
section.SetAttributeValue(nameof(s.AllowMultipleInstances), s.AllowMultipleInstances);
section.SetAttributeValue(nameof(s.LoadPreviousAssemblies), s.LoadPreviousAssemblies);
XElement existingElement = root.Element("MiscSettings");

26
ILSpy/Properties/Resources.Designer.cs generated

@ -1127,6 +1127,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -1127,6 +1127,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Project export.
/// </summary>
public static string DecompilerSettings_ProjectExport {
get {
return ResourceManager.GetString("DecompilerSettings.ProjectExport", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Ranges.
/// </summary>
@ -1316,6 +1325,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -1316,6 +1325,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Use nested directories for namespaces.
/// </summary>
public static string DecompilerSettings_UseNestedDirectoriesForNamespaces {
get {
return ResourceManager.GetString("DecompilerSettings.UseNestedDirectoriesForNamespaces", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use non-trailing named arguments.
/// </summary>
@ -2002,7 +2020,7 @@ namespace ICSharpCode.ILSpy.Properties { @@ -2002,7 +2020,7 @@ namespace ICSharpCode.ILSpy.Properties {
}
/// <summary>
/// Looks up a localized string similar to You can change this by toggling the setting at Options &gt; Decompiler &gt; Other &gt; Use new SDK style format for generated project files (*.csproj)..
/// Looks up a localized string similar to You can change this by toggling the setting at Options &gt; Decompiler &gt; Project export &gt; Use new SDK style format for generated project files (*.csproj)..
/// </summary>
public static string ProjectExportFormatChangeSettingHint {
get {
@ -2029,9 +2047,11 @@ namespace ICSharpCode.ILSpy.Properties { @@ -2029,9 +2047,11 @@ namespace ICSharpCode.ILSpy.Properties {
}
/// <summary>
/// Looks up a localized string similar to Failed to decompile the assemblies {0} because the namespace directory structure is nested too deep.
/// Looks up a localized string similar to Failed to decompile the assemblies {0} because the namespace names are too long or the directory structure is nested too deep.
///
///If you are using Windows 10.0.14393 (Windows 10 version 1607) or later, you can enable &quot;Long path support&quot; by creating a REG_DWORD registry key named &quot;LongPathsEnabled&quot; with value 0x1 at &quot;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem&quot; (see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more information).
///
///If you are using Windows 10.0.14393 (Windows 10 version 1607) or later, you can enable &quot;Long path support&quot; by creating a REG_DWORD registry key named &quot;LongPathsEnabled&quot; with value 0x1 at &quot;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem&quot; (see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more information)..
///If this does not [rest of string was truncated]&quot;;.
/// </summary>
public static string ProjectExportPathTooLong {
get {

14
ILSpy/Properties/Resources.resx

@ -399,6 +399,9 @@ Are you sure you want to continue?</value> @@ -399,6 +399,9 @@ Are you sure you want to continue?</value>
<data name="DecompilerSettings.PatternMatching" xml:space="preserve">
<value>Use pattern matching expressions</value>
</data>
<data name="DecompilerSettings.ProjectExport" xml:space="preserve">
<value>Project export</value>
</data>
<data name="DecompilerSettings.Ranges" xml:space="preserve">
<value>Ranges</value>
</data>
@ -462,6 +465,9 @@ Are you sure you want to continue?</value> @@ -462,6 +465,9 @@ Are you sure you want to continue?</value>
<data name="DecompilerSettings.UseNamedArguments" xml:space="preserve">
<value>Use named arguments</value>
</data>
<data name="DecompilerSettings.UseNestedDirectoriesForNamespaces" xml:space="preserve">
<value>Use nested directories for namespaces</value>
</data>
<data name="DecompilerSettings.UseNonTrailingNamedArguments" xml:space="preserve">
<value>Use non-trailing named arguments</value>
</data>
@ -689,7 +695,7 @@ Please disable all filters that might hide the item (i.e. activate "View &gt; Sh @@ -689,7 +695,7 @@ Please disable all filters that might hide the item (i.e. activate "View &gt; Sh
<value>Portable PDB|*.pdb|All files|*.*</value>
</data>
<data name="ProjectExportFormatChangeSettingHint" xml:space="preserve">
<value>You can change this by toggling the setting at Options &gt; Decompiler &gt; Other &gt; Use new SDK style format for generated project files (*.csproj).</value>
<value>You can change this by toggling the setting at Options &gt; Decompiler &gt; Project export &gt; Use new SDK style format for generated project files (*.csproj).</value>
</data>
<data name="ProjectExportFormatNonSDKHint" xml:space="preserve">
<value>A Non-SDK project was generated. Learn more at https://docs.microsoft.com/en-us/nuget/resources/check-project-format.</value>
@ -698,9 +704,11 @@ Please disable all filters that might hide the item (i.e. activate "View &gt; Sh @@ -698,9 +704,11 @@ Please disable all filters that might hide the item (i.e. activate "View &gt; Sh
<value>A SDK-style project was generated. Learn more at https://docs.microsoft.com/en-us/nuget/resources/check-project-format.</value>
</data>
<data name="ProjectExportPathTooLong" xml:space="preserve">
<value>Failed to decompile the assemblies {0} because the namespace directory structure is nested too deep.
<value>Failed to decompile the assemblies {0} because the namespace names are too long or the directory structure is nested too deep.
If you are using Windows 10.0.14393 (Windows 10 version 1607) or later, you can enable "Long path support" by creating a REG_DWORD registry key named "LongPathsEnabled" with value 0x1 at "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem" (see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more information).
If you are using Windows 10.0.14393 (Windows 10 version 1607) or later, you can enable "Long path support" by creating a REG_DWORD registry key named "LongPathsEnabled" with value 0x1 at "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem" (see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more information).</value>
If this does not solve the problem and your system supports long paths, you can try to use a nested path structure. You can change this by toggling the setting at Options &gt; Decompiler &gt; Project export &gt; Use nested directories for namespaces. This helps because even on "long-path-aware" platforms, the length of a directory name is limited, on Windows/NTFS this is 255 characters.</value>
</data>
<data name="PropertyManuallyMissingReferencesListLoadedAssemblies" xml:space="preserve">
<value>for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.</value>

10
ILSpy/TextView/DecompilerTextView.cs

@ -1034,7 +1034,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -1034,7 +1034,7 @@ namespace ICSharpCode.ILSpy.TextView
SaveFileDialog dlg = new SaveFileDialog();
dlg.DefaultExt = language.FileExtension;
dlg.Filter = language.Name + "|*" + language.FileExtension + Properties.Resources.AllFiles;
dlg.FileName = CleanUpName(treeNodes.First().ToString()) + language.FileExtension;
dlg.FileName = WholeProjectDecompiler.CleanUpFileName(treeNodes.First().ToString()) + language.FileExtension;
if (dlg.ShowDialog() == true)
{
SaveToDisk(new DecompilationContext(language, treeNodes.ToArray(), options), dlg.FileName);
@ -1149,14 +1149,6 @@ namespace ICSharpCode.ILSpy.TextView @@ -1149,14 +1149,6 @@ namespace ICSharpCode.ILSpy.TextView
thread.Start();
return tcs.Task;
}
/// <summary>
/// Cleans up a node name for use as a file name.
/// </summary>
internal static string CleanUpName(string text)
{
return WholeProjectDecompiler.CleanUpFileName(text);
}
#endregion
internal ReferenceSegment? GetReferenceSegmentAtMousePosition()

4
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -26,10 +26,10 @@ using System.Windows.Controls; @@ -26,10 +26,10 @@ using System.Windows.Controls;
using System.Windows.Documents;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.TreeView;
@ -384,7 +384,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -384,7 +384,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (string.IsNullOrEmpty(language.ProjectFileExtension))
return false;
SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = DecompilerTextView.CleanUpName(LoadedAssembly.ShortName) + language.ProjectFileExtension;
dlg.FileName = WholeProjectDecompiler.CleanUpFileName(LoadedAssembly.ShortName) + language.ProjectFileExtension;
dlg.Filter = language.Name + " project|*" + language.ProjectFileExtension + "|" + language.Name + " single file|*" + language.FileExtension + "|All files|*.*";
if (dlg.ShowDialog() == true)
{

4
ILSpy/TreeNodes/ResourceNodes/ResourceEntryNode.cs

@ -20,8 +20,8 @@ using System; @@ -20,8 +20,8 @@ using System;
using System.IO;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
using Microsoft.Win32;
@ -80,7 +80,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -80,7 +80,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool Save(ViewModels.TabPageModel tabPage)
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = Path.GetFileName(DecompilerTextView.CleanUpName(key));
dlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(key));
if (dlg.ShowDialog() == true)
{
using var data = OpenStream();

5
ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs

@ -24,6 +24,7 @@ using System.Text; @@ -24,6 +24,7 @@ using System.Text;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
@ -91,7 +92,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -91,7 +92,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (type == FileType.Xml)
ext = ".xml";
else
ext = Path.GetExtension(DecompilerTextView.CleanUpName(Resource.Name));
ext = Path.GetExtension(WholeProjectDecompiler.SanitizeFileName(Resource.Name));
tabPage.ShowTextView(textView => textView.ShowNode(output, this, HighlightingManager.Instance.GetDefinitionByExtension(ext)));
tabPage.SupportsLanguageSwitching = false;
return true;
@ -106,7 +107,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -106,7 +107,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (s == null)
return false;
SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = DecompilerTextView.CleanUpName(Resource.Name);
dlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(Resource.Name));
if (dlg.ShowDialog() == true)
{
s.Position = 0;

3
ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs

@ -24,6 +24,7 @@ using System.IO; @@ -24,6 +24,7 @@ using System.IO;
using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.Controls;
@ -129,7 +130,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -129,7 +130,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (s == null)
return false;
SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = DecompilerTextView.CleanUpName(Resource.Name);
dlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(Resource.Name));
dlg.Filter = Resources.ResourcesFileFilter;
if (dlg.ShowDialog() == true)
{

Loading…
Cancel
Save