Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when Attempting to Decompile Microsoft.Exchange.Monitoring.ActiveMonitoring.Local.Components.dll And Stops All Decompilation #2622

Closed
gwillcox-r7 opened this issue Feb 5, 2022 · 8 comments
Labels

Comments

@gwillcox-r7
Copy link

gwillcox-r7 commented Feb 5, 2022

Steps to reproduce

  1. Get a copy of Microsoft.Exchange.Monitoring.ActiveMonitoring.Local.Components.dll from one of the Exchange 2019 patch files such as https://download.microsoft.com/download/b/a/1/ba1bf2f2-91f1-4670-882f-2d62506444e0/Exchange2019-KB5007409-x64-en.msp. Sorry not sharing it here due to potential copywrite issues, but if you have trouble finding it, let me know.
  2. Load it into ILSpy and attempt to export this code along with other DLLs from the patch into a project file.
  3. Find that not only does it crash, but also all of the decompilation stops at this point, leaving the decompiled state in an half finished state instead of fully completing despite the error.

Error message shown

Failed to decompile the assembly 'C:\Users\gwillcox\Documents\CVE-2021-42321\Before\Microsoft.Exchange.Monitoring.ActiveMonitoring.Local.Components.dll':
System.AggregateException: One or more errors occurred. ---> System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\gwillcox\Documents\CVE-2021-42321\Before\Dec IlSpy\Microsoft.Exchange.Monitoring.ActiveMonitoring.Local.Components\Microsoft\Exchange\Monitoring\ActiveMonitoring\Local\CafeV2\Probes\Detectors\HttpRequestDetectors\SmokeTestDetector\SmokeTestDetector.cs'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.<>c__DisplayClass45_0.<WriteCodeFilesInProject>b__2(IGrouping`2 file) in /_/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs:line 233
   at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
   at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Parallel.PartitionerForEachWorker[TSource,TLocal](Partitioner`1 source, ParallelOptions parallelOptions, Action`1 simpleBody, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)
   at System.Threading.Tasks.Parallel.ForEach[TSource](Partitioner`1 source, ParallelOptions parallelOptions, Action`1 body)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.WriteCodeFilesInProject(PEFile module, CancellationToken cancellationToken) in /_/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs:line 249
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.DecompileProject(PEFile moduleDefinition, String targetDirectory, TextWriter projectFileWriter, CancellationToken cancellationToken) in /_/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs:line 149
   at ICSharpCode.ILSpy.CSharpLanguage.DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
   at ICSharpCode.ILSpy.SolutionWriter.WriteProject(LoadedAssembly loadedAssembly, Language language, String targetDirectory, CancellationToken ct)
---> (Inner Exception #0) System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\gwillcox\Documents\CVE-2021-42321\Before\Dec IlSpy\Microsoft.Exchange.Monitoring.ActiveMonitoring.Local.Components\Microsoft\Exchange\Monitoring\ActiveMonitoring\Local\CafeV2\Probes\Detectors\HttpRequestDetectors\SmokeTestDetector\SmokeTestDetector.cs'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.<>c__DisplayClass45_0.<WriteCodeFilesInProject>b__2(IGrouping`2 file) in /_/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs:line 233
   at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
   at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)<---

-------------
Failed to decompile the assembly 'C:\Users\gwillcox\Documents\CVE-2021-42321\Before\Microsoft.Exchange.Services.EwsHandler.dll':
System.AggregateException: One or more errors occurred. ---> ICSharpCode.Decompiler.DecompilerException: Error decompiling @060002F0 Microsoft.Exchange.Services.Wcf.EWSServiceHostFactory.CreateServiceHost ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at ICSharpCode.Decompiler.CSharp.CallBuilder.BuildArgumentList(ExpectedTargetDetails expectedTargetDetails, ResolveResult target, IMethod method, Int32 firstParamIndex, IReadOnlyList`1 callArguments, IReadOnlyList`1 argumentToParameterMap) in /_/ICSharpCode.Decompiler/CSharp/CallBuilder.cs:line 710
   at ICSharpCode.Decompiler.CSharp.CallBuilder.BuildDictionaryInitializerExpression(OpCode callOpCode, IMethod method, InitializedObjectResolveResult target, IReadOnlyList`1 indices, ILInstruction value) in /_/ICSharpCode.Decompiler/CSharp/CallBuilder.cs:line 539
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.MakeInitializerAssignment(InitializedObjectResolveResult rr, AccessPathElement memberPath, AccessPathElement valuePath, List`1 values, Dictionary`2 indexVariables) in /_/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs:line 3311
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.BuildArrayInitializerExpression(Block block, InitializedObjectResolveResult initObjRR) in /_/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs:line 3267
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.TranslateObjectAndCollectionInitializer(Block block) in /_/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs:line 3179
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.VisitBlock(Block block, TranslationContext context) in /_/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs:line 3108
   at ICSharpCode.Decompiler.IL.Block.AcceptVisitor[C,T](ILVisitor`2 visitor, C context) in /_/ICSharpCode.Decompiler/IL/Instructions.cs:line 876
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.Translate(ILInstruction inst, IType typeHint) in /_/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs:line 161
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.VisitLeave(Leave inst) in /_/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs:line 383
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.Convert(ILInstruction inst) in /_/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs:line 78
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertBlockContainer(BlockStatement blockStatement, BlockContainer container, IEnumerable`1 blocks, Boolean isLoop) in /_/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs:line 1383
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertBlockContainer(BlockContainer container, Boolean isLoop) in /_/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs:line 1328
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.VisitBlockContainer(BlockContainer container) in /_/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs:line 1215
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.Convert(ILInstruction inst) in /_/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs:line 78
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertAsBlock(ILInstruction inst) in /_/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs:line 83
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in /_/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs:line 1564
   --- End of inner exception stack trace ---
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in /_/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs:line 1588
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DoDecompile(IMethod method, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in /_/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs:line 1465
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in /_/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs:line 1318
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DoDecompileTypes(IEnumerable`1 types, DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree) in /_/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs:line 574
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DecompileTypes(IEnumerable`1 types) in /_/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs:line 895
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.<>c__DisplayClass45_0.<WriteCodeFilesInProject>b__2(IGrouping`2 file) in /_/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs:line 238
   at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
   at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Parallel.PartitionerForEachWorker[TSource,TLocal](Partitioner`1 source, ParallelOptions parallelOptions, Action`1 simpleBody, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)
   at System.Threading.Tasks.Parallel.ForEach[TSource](Partitioner`1 source, ParallelOptions parallelOptions, Action`1 body)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.WriteCodeFilesInProject(PEFile module, CancellationToken cancellationToken) in /_/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs:line 249
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.DecompileProject(PEFile moduleDefinition, String targetDirectory, TextWriter projectFileWriter, CancellationToken cancellationToken) in /_/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs:line 149
   at ICSharpCode.ILSpy.CSharpLanguage.DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
   at ICSharpCode.ILSpy.SolutionWriter.WriteProject(LoadedAssembly loadedAssembly, Language language, String targetDirectory, CancellationToken ct)
---> (Inner Exception #0) Error decompiling @060002F0 Microsoft.Exchange.Services.Wcf.EWSServiceHostFactory.CreateServiceHost
in assembly "C:\Users\gwillcox\Documents\CVE-2021-42321\Before\Microsoft.Exchange.Services.EwsHandler.dll"
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at ICSharpCode.Decompiler.CSharp.CallBuilder.BuildArgumentList(ExpectedTargetDetails expectedTargetDetails, ResolveResult target, IMethod method, Int32 firstParamIndex, IReadOnlyList`1 callArguments, IReadOnlyList`1 argumentToParameterMap) in CallBuilder.cs:line 710
   at ICSharpCode.Decompiler.CSharp.CallBuilder.BuildDictionaryInitializerExpression(OpCode callOpCode, IMethod method, InitializedObjectResolveResult target, IReadOnlyList`1 indices, ILInstruction value) in CallBuilder.cs:line 539
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.MakeInitializerAssignment(InitializedObjectResolveResult rr, AccessPathElement memberPath, AccessPathElement valuePath, List`1 values, Dictionary`2 indexVariables) in ExpressionBuilder.cs:line 3311
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.BuildArrayInitializerExpression(Block block, InitializedObjectResolveResult initObjRR) in ExpressionBuilder.cs:line 3267
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.TranslateObjectAndCollectionInitializer(Block block) in ExpressionBuilder.cs:line 3179
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.VisitBlock(Block block, TranslationContext context) in ExpressionBuilder.cs:line 3108
   at ICSharpCode.Decompiler.IL.Block.AcceptVisitor[C,T](ILVisitor`2 visitor, C context) in Instructions.cs:line 876
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.Translate(ILInstruction inst, IType typeHint) in ExpressionBuilder.cs:line 161
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.VisitLeave(Leave inst) in StatementBuilder.cs:line 383
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.Convert(ILInstruction inst) in StatementBuilder.cs:line 78
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertBlockContainer(BlockStatement blockStatement, BlockContainer container, IEnumerable`1 blocks, Boolean isLoop) in StatementBuilder.cs:line 1383
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertBlockContainer(BlockContainer container, Boolean isLoop) in StatementBuilder.cs:line 1328
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.VisitBlockContainer(BlockContainer container) in StatementBuilder.cs:line 1215
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.Convert(ILInstruction inst) in StatementBuilder.cs:line 78
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertAsBlock(ILInstruction inst) in StatementBuilder.cs:line 83
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in CSharpDecompiler.cs:line 1564
-- continuing with outer exception (ICSharpCode.Decompiler.DecompilerException) --
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in CSharpDecompiler.cs:line 1588
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DoDecompile(IMethod method, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in CSharpDecompiler.cs:line 1465
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in CSharpDecompiler.cs:line 1318
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DoDecompileTypes(IEnumerable`1 types, DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree) in CSharpDecompiler.cs:line 574
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DecompileTypes(IEnumerable`1 types) in CSharpDecompiler.cs:line 895
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.<>c__DisplayClass45_0.<WriteCodeFilesInProject>b__2(IGrouping`2 file) in WholeProjectDecompiler.cs:line 238
   at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1() in offset 713
   at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask) in offset 6
   at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>) in offset 134<---

-------------

Details

  • ILSpy
  • Version in use: 7.2.0.6791-preview3 with .NET Version 4.8.4360.0 on Windows 11.
  • Happy to assist with debugging this further, as right now this issue is causing me to have to use dnSpy since its not hitting the same issues when decompiling the same files. I'd ideally like to try resolve this issue so that in the event that I do have to decompile .NET 5.0 or later files, that ILSpy would be able to perform similar whole project decompilations for the purposes of patch diffing.
  • For reference this was encountered whilst trying to do patch diffing for CVE-2021-42321 to understand the bug more which is why you might see a few references to this in the file paths above. Hopefully not an issue but if it is related I'd be interested.
@gwillcox-r7 gwillcox-r7 added the Bug label Feb 5, 2022
@siegfriedpammer
Copy link
Member

System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\gwillcox\Documents\CVE-2021-42321\Before\Dec IlSpy\Microsoft.Exchange.Monitoring.ActiveMonitoring.Local.Components\Microsoft\Exchange\Monitoring\ActiveMonitoring\Local\CafeV2\Probes\Detectors\HttpRequestDetectors\SmokeTestDetector\SmokeTestDetector.cs'.

The path is exactly 260 characters long... I don't have access to Windows 11 yet. Not sure, if Long Path Support is enabled by default. You might have to enable it 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). These instructions are for Windows 10, I am not sure if something (or what) changed in Windows 11.

The second exception is a decompiler bug, which I will try to reproduce and fix. Thanks for reporting!

siegfriedpammer added a commit that referenced this issue Feb 6, 2022
@gwillcox-r7
Copy link
Author

System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\gwillcox\Documents\CVE-2021-42321\Before\Dec IlSpy\Microsoft.Exchange.Monitoring.ActiveMonitoring.Local.Components\Microsoft\Exchange\Monitoring\ActiveMonitoring\Local\CafeV2\Probes\Detectors\HttpRequestDetectors\SmokeTestDetector\SmokeTestDetector.cs'.

The path is exactly 260 characters long... I don't have access to Windows 11 yet. Not sure, if Long Path Support is enabled by default. You might have to enable it 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). These instructions are for Windows 10, I am not sure if something (or what) changed in Windows 11.

The second exception is a decompiler bug, which I will try to reproduce and fix. Thanks for reporting!

Thanks, will see if the LongPathsEnabled setting works, as I don't think that is enabled by default and near as I can tell Windows 11 shouldn't have changed that I don't think?

Appreciate your work on a fix!

@gwillcox-r7
Copy link
Author

Sorry closed this as I thought it was working but whilst the issue is fixed if I do an individual file decompile its still occurring if I try decompile multiple files at the same time with this DLL in it.

@gwillcox-r7
Copy link
Author

Update: Seems like applying the regex fix from https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation that @siegfriedpammer mentions allows for successful decompilation on 7.2.0.6839-preview4 when batch decompiling multiple files into a solution.

Therefore whilst the root issue is likely still there, this does work as a workaround in the meantime, and it also seems to still work on Windows 11.

@siegfriedpammer
Copy link
Member

Therefore whilst the root issue is likely still there.

The root cause is the file system limitation, which we cannot (completely) and won't work around, because Microsoft already fixed it by introducing "Long Path Support" in their OS.

As a workaround you could always set "C:\out" (or something even shorter) as output directory to maximize your chances of success. Any workaround from our side would mean crippling namespace names and filenames, which we decided is not a good idea. When long paths are not supported we limit the length of whole path to 250 characters and each segment to 30 characters (as you can see here: https://github.com/icsharpcode/ILSpy/blob/master/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs#L559).

Sorry!

@gwillcox-r7
Copy link
Author

Ah fair point and thanks for linking to the code that makes a lot more sense 👍 Only thing I would say is that from a user perspective its kind of hard to know this might be an issue the way the interface and warnings currently are so I think adding a warning to the end user about this might be useful in case others run into similar issues, just as a quick debugging tip.

Otherwise happy to have this issue closed, and appreciate your patience and help on this!

@siegfriedpammer
Copy link
Member

siegfriedpammer commented Feb 8, 2022

I think adding a warning to the end user about this might be useful in case others run into similar issues, just as a quick debugging tip.

Unfortunately the exceptions thrown in these cases are not very descriptive (in your case it was reported as DirectoryNotFoundException, which is certainly not a useful hint at the actual problem...). We already handle PathTooLongException (see https://github.com/icsharpcode/ILSpy/blob/master/ILSpy/TextView/DecompilerTextView.cs#L1103).

We show the following message in that case:

"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 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 > Decompiler > Project export > 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."

However, System.IO unfortunately is a bit messy in this case. I suspect this is because "Long Path Support" was bolted onto it at a relatively late stage in the product life-cycle and it seems they missed the "is the path too long? throw new PathTooLongException();" in some cases.

Anyway, do you consider this fixed? If yes, please close the issue, thanks!

@gwillcox-r7
Copy link
Author

Thanks for the explanation, makes sense. Marking this as closed and resolved!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants