Search code examples
c#.netprocess.startassembly-loading

EXE (plus dependant DLLs) copied to temp folder and launched still loads DLLs from original folder


I have a main application that uses a separate "Package Installer" application to update itself when a newer version is available. This update would include the main application, all DLL dependencies, plus the Package Installer itself. The process works like this:

  1. Main app detects a version upgrade is available
  2. Main app copies the Package Installer EXE to a temp folder, plus the DLLs it depends on and the DLL they depend on. In other words, the minimum components necessary to run the Package Installer are copied to the temp folder.
  3. Main app runs Package Installer from the temp folder using Process.Start
  4. Main app shuts down
  5. Package Installer copies new EXEs & DLLs into app folder
  6. Package Installer starts main app again
  7. Package Installer shuts down

Step 5 always fails due to the Package Installer being unable to overwrite files that are in use. The files are DLLs that the Package Installer itself has loaded from the app folder. These are DLLs that have no direct or indirect references to the Package Installer.

I have verified (using Windows Resource Monitor) that it is the Package Installer (and only that EXE) that has loaded the DLLs from the app folder. I have also double-checked that there are no references from the Package Installer project to these DLLs, either directly or through another DLL. I have also verified that the Package Installer loads the DLLs that it is dependant on (the 3 mentioned above) from the temp folder.

Finally, I have tried copying the entire application (every EXE & DLL) into the temp folder before running the Package Installer, but even then there is still some DLL that it loads from the app folder (not the ones mentioned above this time, but 3rd party DLLs).

What is going on and what can I do to suppress the loading of the extra DLLs?


Solution

  • Check out the MSDN documentation for ProcessStartInfo.WorkingDirectory. It notes that When UseShellExecute is true, the working directory of the application that starts the executable is also the working directory of the executable.

    ProcessStartInfo startInfo = new ProcessStartInfo("c:\\path\\to\\filename.exe");
    startInfo.UseShellExecute = false;
    Process.Start(startInfo);
    

    And if that doesn't work, try startInfo.WorkingDirectory = "c:\\path\\to";