mercredi 29 septembre 2021

Renamed WPF exe throws FileNotFoundException (not typical)

I have a WPF exe that after being built, if the exe is renamed, will not run because a FileNotFoundException is thrown. I have never seen this in ten years of working with .NET executables and this is not supposed to be a problem. Our exe name is built as "Installer.exe", but if we rename it to anything else and try to run it it fails with the following call stack:

Application: test.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException
   at System.Reflection.RuntimeAssembly._nLoad(System.Reflection.AssemblyName, System.String, System.Security.Policy.Evidence, System.Reflection.RuntimeAssembly, System.Threading.StackCrawlMark ByRef, IntPtr, Boolean, Boolean, Boolean)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(System.Reflection.AssemblyName, System.Security.Policy.Evidence, System.Reflection.RuntimeAssembly, System.Threading.StackCrawlMark ByRef, IntPtr, Boolean, Boolean, Boolean)
   at System.Reflection.Assembly.Load(System.Reflection.AssemblyName)
   at System.Windows.Navigation.BaseUriHelper.GetLoadedAssembly(System.String, System.String, System.String)
   at MS.Internal.AppModel.ResourceContainer.GetResourceManagerWrapper(System.Uri, System.String ByRef, Boolean ByRef)
   at MS.Internal.AppModel.ResourceContainer.GetPartCore(System.Uri)
   at System.IO.Packaging.Package.GetPartHelper(System.Uri)
   at System.IO.Packaging.Package.GetPart(System.Uri)
   at System.Windows.Application.GetResourceOrContentPart(System.Uri)
   at System.Windows.Application.LoadComponent(System.Object, System.Uri)
   at Installer.App.InitializeComponent()
   at Installer.App.Main()

If I debug the executable I can further expand that to:

System.IO.FileNotFoundException: 'Could not load file or assembly 'Installer, Version=1.0.0.0,
Culture=neutral' or one of its dependencies. The system cannot find the file specified.'

I have also investigated the Fusion Log:

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\Users\dande\Downloads\test.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = Installer, Version=1.0.0.0, Culture=neutral
 (Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: Installer, Version=1.0.0.0, Culture=neutral | Domain ID: 1
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.
WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
LOG: Appbase = file:///C:/Users/dande/Downloads/
LOG: Initial PrivatePath = NULL
Calling assembly : PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Users/dande/Downloads/Installer.DLL.
LOG: Attempting download of new URL file:///C:/Users/dande/Downloads/Installer/Installer.DLL.
LOG: Attempting download of new URL file:///C:/Users/dande/Downloads/Installer.EXE.
LOG: Attempting download of new URL file:///C:/Users/dande/Downloads/Installer/Installer.EXE.

And I have investigated and ruled out the following:

  • We are not using Assembly.Load to load 'Installer' (which is the executing assembly)
  • We do not have any pack:// usages in XAML.
  • We have no code analysis warnings, errors, or XAML errors
  • It is not related to a application configuration file
  • It is not related to the application manifest
  • Application crashes even if I change the code to use a normal Window and not our MainWindow (eliminating a lot of XAML from the equation)
  • .NET version doesn't make a difference. It's targeting and built for .NET 4.6, but changing this doesn't change the outcome
  • Confirmed that all dependencies are referenced/present using DotPeek/JustDecompile
  • Confirmed that all namespaces internally are still 'Installer'
  • Investigated the partial binding via reading documentation, but this isn't a reference issue, the error indicates its the executing assembly itself that is the issue (it's looking for itself?)
  • Is not related to code signing as it occurs with or without it
  • It is not related to strong name signing as we are not using that

Things I have observed:

  • This happens prior to OnStartup. I cannot debug into the application.
  • It appears to be PresentationCore.dll (from Fusion Log) originating this issue
  • Confirmed with ProcMon.exe that it is in fact trying to access one of the four logged fusion log paths (Installer.DLL, Installer/Installer.DLL, Installer.EXE, Installer.Installer.EXE)
  • This occurs on any environment and I can reproduce locally by building the solution then renaming, the output file and then running it
  • If I copy the executable and rename that and run it it works fine because Installer.exe is present in the same directory

I have never seen this problem before and researching it I have not been successful because I'm just finding all the basic stuff new developers typically run into with reference problems and the like.

My only assumption is that possibly its XAML related but I haven't found anything in XAML out of the ordinary and we don't have any pack:// usages or anything.





Aucun commentaire:

Enregistrer un commentaire