Unload a .NET DLL from an unmanaged process












21















I'm extending my Inno-Setup script with code that I can best implement in C# in a managed DLL. I already know how to export methods from a managed DLL as functions for use in an unmanaged process. It can be done by IL weaving, and there are tools to automate this:





  • NetDllExport (written by me)

  • UnmanagedExports


So after exporting, I can call my functions from Pascal script in an Inno-Setup installer. But then there's one issue: The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive.



I know that managed assemblies cannot be unloaded from an AppDomain anymore, unless the entire AppDomain is shut down (the process exits). But what does it mean to the unmanaged host process?



Is there a better way to allow Inno-Setup to unload or delete my DLL file after loading and using it?










share|improve this question




















  • 1





    Small potatoes compared to uninstalling the .NET version you needed to get your installer going. If you don't know how to debug the exception then ask that question instead.

    – Hans Passant
    Feb 7 '15 at 23:12






  • 2





    The .NET runtime is required for my installed application anyway, so it won't be uninstalled again.

    – ygoe
    Feb 7 '15 at 23:39











  • BTW, .NET is a Windows operating system component for some time now, and only the latest version is supported anyway. So .NET should already be there, should not go away, and might even be considered ubiquitous on Windows.

    – ygoe
    May 22 '16 at 10:06











  • Scratch "un". .NET 3.5SP1 is still supported, Win7 is the new XP. Of the 3 ways to run managed code from an unmanaged program, this one is by far the most miserable. Any mishap is completely undiagnosable and that includes the ones you can never catch because they happen before the code starts running. Do yourself a favor and at least try it, throw an exception to see what it looks like.

    – Hans Passant
    May 22 '16 at 17:45






  • 1





    @caesay An alternative is to use COM interop to expose managed code to an unmanaged program: see msdn.microsoft.com/en-us/library/…

    – Rodney Richardson
    Nov 22 '16 at 10:26
















21















I'm extending my Inno-Setup script with code that I can best implement in C# in a managed DLL. I already know how to export methods from a managed DLL as functions for use in an unmanaged process. It can be done by IL weaving, and there are tools to automate this:





  • NetDllExport (written by me)

  • UnmanagedExports


So after exporting, I can call my functions from Pascal script in an Inno-Setup installer. But then there's one issue: The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive.



I know that managed assemblies cannot be unloaded from an AppDomain anymore, unless the entire AppDomain is shut down (the process exits). But what does it mean to the unmanaged host process?



Is there a better way to allow Inno-Setup to unload or delete my DLL file after loading and using it?










share|improve this question




















  • 1





    Small potatoes compared to uninstalling the .NET version you needed to get your installer going. If you don't know how to debug the exception then ask that question instead.

    – Hans Passant
    Feb 7 '15 at 23:12






  • 2





    The .NET runtime is required for my installed application anyway, so it won't be uninstalled again.

    – ygoe
    Feb 7 '15 at 23:39











  • BTW, .NET is a Windows operating system component for some time now, and only the latest version is supported anyway. So .NET should already be there, should not go away, and might even be considered ubiquitous on Windows.

    – ygoe
    May 22 '16 at 10:06











  • Scratch "un". .NET 3.5SP1 is still supported, Win7 is the new XP. Of the 3 ways to run managed code from an unmanaged program, this one is by far the most miserable. Any mishap is completely undiagnosable and that includes the ones you can never catch because they happen before the code starts running. Do yourself a favor and at least try it, throw an exception to see what it looks like.

    – Hans Passant
    May 22 '16 at 17:45






  • 1





    @caesay An alternative is to use COM interop to expose managed code to an unmanaged program: see msdn.microsoft.com/en-us/library/…

    – Rodney Richardson
    Nov 22 '16 at 10:26














21












21








21


4






I'm extending my Inno-Setup script with code that I can best implement in C# in a managed DLL. I already know how to export methods from a managed DLL as functions for use in an unmanaged process. It can be done by IL weaving, and there are tools to automate this:





  • NetDllExport (written by me)

  • UnmanagedExports


So after exporting, I can call my functions from Pascal script in an Inno-Setup installer. But then there's one issue: The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive.



I know that managed assemblies cannot be unloaded from an AppDomain anymore, unless the entire AppDomain is shut down (the process exits). But what does it mean to the unmanaged host process?



Is there a better way to allow Inno-Setup to unload or delete my DLL file after loading and using it?










share|improve this question
















I'm extending my Inno-Setup script with code that I can best implement in C# in a managed DLL. I already know how to export methods from a managed DLL as functions for use in an unmanaged process. It can be done by IL weaving, and there are tools to automate this:





  • NetDllExport (written by me)

  • UnmanagedExports


So after exporting, I can call my functions from Pascal script in an Inno-Setup installer. But then there's one issue: The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive.



I know that managed assemblies cannot be unloaded from an AppDomain anymore, unless the entire AppDomain is shut down (the process exits). But what does it mean to the unmanaged host process?



Is there a better way to allow Inno-Setup to unload or delete my DLL file after loading and using it?







c# .net com inno-setup unmanaged






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 20 '16 at 8:16









caesay

10.7k1172141




10.7k1172141










asked Feb 7 '15 at 22:15









ygoeygoe

5,8741567125




5,8741567125








  • 1





    Small potatoes compared to uninstalling the .NET version you needed to get your installer going. If you don't know how to debug the exception then ask that question instead.

    – Hans Passant
    Feb 7 '15 at 23:12






  • 2





    The .NET runtime is required for my installed application anyway, so it won't be uninstalled again.

    – ygoe
    Feb 7 '15 at 23:39











  • BTW, .NET is a Windows operating system component for some time now, and only the latest version is supported anyway. So .NET should already be there, should not go away, and might even be considered ubiquitous on Windows.

    – ygoe
    May 22 '16 at 10:06











  • Scratch "un". .NET 3.5SP1 is still supported, Win7 is the new XP. Of the 3 ways to run managed code from an unmanaged program, this one is by far the most miserable. Any mishap is completely undiagnosable and that includes the ones you can never catch because they happen before the code starts running. Do yourself a favor and at least try it, throw an exception to see what it looks like.

    – Hans Passant
    May 22 '16 at 17:45






  • 1





    @caesay An alternative is to use COM interop to expose managed code to an unmanaged program: see msdn.microsoft.com/en-us/library/…

    – Rodney Richardson
    Nov 22 '16 at 10:26














  • 1





    Small potatoes compared to uninstalling the .NET version you needed to get your installer going. If you don't know how to debug the exception then ask that question instead.

    – Hans Passant
    Feb 7 '15 at 23:12






  • 2





    The .NET runtime is required for my installed application anyway, so it won't be uninstalled again.

    – ygoe
    Feb 7 '15 at 23:39











  • BTW, .NET is a Windows operating system component for some time now, and only the latest version is supported anyway. So .NET should already be there, should not go away, and might even be considered ubiquitous on Windows.

    – ygoe
    May 22 '16 at 10:06











  • Scratch "un". .NET 3.5SP1 is still supported, Win7 is the new XP. Of the 3 ways to run managed code from an unmanaged program, this one is by far the most miserable. Any mishap is completely undiagnosable and that includes the ones you can never catch because they happen before the code starts running. Do yourself a favor and at least try it, throw an exception to see what it looks like.

    – Hans Passant
    May 22 '16 at 17:45






  • 1





    @caesay An alternative is to use COM interop to expose managed code to an unmanaged program: see msdn.microsoft.com/en-us/library/…

    – Rodney Richardson
    Nov 22 '16 at 10:26








1




1





Small potatoes compared to uninstalling the .NET version you needed to get your installer going. If you don't know how to debug the exception then ask that question instead.

– Hans Passant
Feb 7 '15 at 23:12





Small potatoes compared to uninstalling the .NET version you needed to get your installer going. If you don't know how to debug the exception then ask that question instead.

– Hans Passant
Feb 7 '15 at 23:12




2




2





The .NET runtime is required for my installed application anyway, so it won't be uninstalled again.

– ygoe
Feb 7 '15 at 23:39





The .NET runtime is required for my installed application anyway, so it won't be uninstalled again.

– ygoe
Feb 7 '15 at 23:39













BTW, .NET is a Windows operating system component for some time now, and only the latest version is supported anyway. So .NET should already be there, should not go away, and might even be considered ubiquitous on Windows.

– ygoe
May 22 '16 at 10:06





BTW, .NET is a Windows operating system component for some time now, and only the latest version is supported anyway. So .NET should already be there, should not go away, and might even be considered ubiquitous on Windows.

– ygoe
May 22 '16 at 10:06













Scratch "un". .NET 3.5SP1 is still supported, Win7 is the new XP. Of the 3 ways to run managed code from an unmanaged program, this one is by far the most miserable. Any mishap is completely undiagnosable and that includes the ones you can never catch because they happen before the code starts running. Do yourself a favor and at least try it, throw an exception to see what it looks like.

– Hans Passant
May 22 '16 at 17:45





Scratch "un". .NET 3.5SP1 is still supported, Win7 is the new XP. Of the 3 ways to run managed code from an unmanaged program, this one is by far the most miserable. Any mishap is completely undiagnosable and that includes the ones you can never catch because they happen before the code starts running. Do yourself a favor and at least try it, throw an exception to see what it looks like.

– Hans Passant
May 22 '16 at 17:45




1




1





@caesay An alternative is to use COM interop to expose managed code to an unmanaged program: see msdn.microsoft.com/en-us/library/…

– Rodney Richardson
Nov 22 '16 at 10:26





@caesay An alternative is to use COM interop to expose managed code to an unmanaged program: see msdn.microsoft.com/en-us/library/…

– Rodney Richardson
Nov 22 '16 at 10:26












5 Answers
5






active

oldest

votes


















2














As suggested in other answers, you can launch a separate process at the end of the installation that will take care of the cleanup, after the installation processes finishes.



A simple solution is creating an ad-hoc batch file that loops until the DLL file can be deleted and then also deletes the (now empty) temporary folder and itself.



procedure DeinitializeSetup();
var
FilePath: string;
BatchPath: string;
S: TArrayOfString;
ResultCode: Integer;
begin
FilePath := ExpandConstant('{tmp}MyAssembly.dll');
if not FileExists(FilePath) then
begin
Log(Format('File %s does not exist', [FilePath]));
end
else
begin
BatchPath :=
ExpandConstant('{%TEMP}') +
'delete_' + ExtractFileName(ExpandConstant('{tmp}')) + '.bat';
SetArrayLength(S, 7);
S[0] := ':loop';
S[1] := 'del "' + FilePath + '"';
S[2] := 'if not exist "' + FilePath + '" goto end';
S[3] := 'goto loop';
S[4] := ':end';
S[5] := 'rd "' + ExpandConstant('{tmp}') + '"';
S[6] := 'del "' + BatchPath + '"';
if not SaveStringsToFile(BatchPath, S, False) then
begin
Log(Format('Error creating batch file %s to delete %s', [BatchPath, FilePath]));
end
else
if not Exec(BatchPath, '', '', SW_HIDE, ewNoWait, ResultCode) then
begin
Log(Format('Error executing batch file %s to delete %s', [BatchPath, FilePath]));
end
else
begin
Log(Format('Executed batch file %s to delete %s', [BatchPath, FilePath]));
end;
end;
end;





share|improve this answer

































    1














    You could add a batch script (in the form of running cmd -c) to be executed at the end of setup that waits for the file to be deletable and deletes it. (just make sure to set the inno option to not wait for the cmd process to complete)



    You could also make your installed program detect and delete it on first execution.






    share|improve this answer































      1














      As suggested in this Code Project Article : https://www.codeproject.com/kb/threads/howtodeletecurrentprocess.aspx



      call a cmd with arguments as shown below.



       Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " +  Application.ExecutablePath);


      But basically as @Sean suggested, make sure you dont wait for the cmd.exe to exit in your script.






      share|improve this answer
























      • For this to be reliable, you have to wait for the installer process to finish. Waiting a fixed time is not hardly reliable.

        – Martin Prikryl
        Jan 8 '17 at 10:24



















      0














      While not exactly an answer to your question, can't you just mark the DLL to be deleted next time the computer is restarted?






      share|improve this answer



















      • 9





        If I'm not mistaken, you should add this as a comment to the question itself

        – Matías Fidemraizer
        Feb 7 '15 at 22:19











      • While this is a possible work-around, its not ideal, doesnt answer the question, and doesn't explain the reason that unloading the DLL fails in the first place.

        – caesay
        May 20 '16 at 0:38



















      -1














      The easy way to do what you want is through an AppDomain. You can unload an AppDomain, just not the initial one. So the solution is to create a new AppDomain, load your managed DLL in that and then unload the AppDomain.



              AppDomain ad = AppDomain.CreateDomain("Isolate DLL");
      Assembly a = ad.Load(new AssemblyName("MyManagedDll"));
      object d = a.CreateInstance("MyManagedDll.MyManagedClass");
      Type t = d.GetType();
      double result = (double)t.InvokeMember("Calculate", BindingFlags.InvokeMethod, null, d, new object { 1.0, 2.0 });
      AppDomain.Unload(ad);


      Here is what the DLL code looks like...



      namespace MyManagedDll
      {
      public class MyManagedClass
      {
      public double Calculate(double a, double b)
      {
      return a + b;
      }
      }
      }





      share|improve this answer



















      • 1





        That's irrelevant to the OP. The OP wants to implement an extension to an existing unmanaged application in .NET. OP cannot create new AppDomain, as he/she does not control the DLL loading process.

        – Martin Prikryl
        Feb 13 '17 at 19:26













      • It is indeed relevant. He can get to a managed DLL. That managed DLL simply creates an App Domain and loads another managed DLL which is then unloaded. So what was missing from my answer is that 2 managed DLLs would be required. I simply thought that was obvious.

        – AQuirky
        Feb 14 '17 at 19:45











      • Yes it was obvious. But the problem the OP has is: "The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive." - That your answer cannot solve that problem.

        – Martin Prikryl
        Feb 14 '17 at 19:59













      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f28388095%2funload-a-net-dll-from-an-unmanaged-process%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      2














      As suggested in other answers, you can launch a separate process at the end of the installation that will take care of the cleanup, after the installation processes finishes.



      A simple solution is creating an ad-hoc batch file that loops until the DLL file can be deleted and then also deletes the (now empty) temporary folder and itself.



      procedure DeinitializeSetup();
      var
      FilePath: string;
      BatchPath: string;
      S: TArrayOfString;
      ResultCode: Integer;
      begin
      FilePath := ExpandConstant('{tmp}MyAssembly.dll');
      if not FileExists(FilePath) then
      begin
      Log(Format('File %s does not exist', [FilePath]));
      end
      else
      begin
      BatchPath :=
      ExpandConstant('{%TEMP}') +
      'delete_' + ExtractFileName(ExpandConstant('{tmp}')) + '.bat';
      SetArrayLength(S, 7);
      S[0] := ':loop';
      S[1] := 'del "' + FilePath + '"';
      S[2] := 'if not exist "' + FilePath + '" goto end';
      S[3] := 'goto loop';
      S[4] := ':end';
      S[5] := 'rd "' + ExpandConstant('{tmp}') + '"';
      S[6] := 'del "' + BatchPath + '"';
      if not SaveStringsToFile(BatchPath, S, False) then
      begin
      Log(Format('Error creating batch file %s to delete %s', [BatchPath, FilePath]));
      end
      else
      if not Exec(BatchPath, '', '', SW_HIDE, ewNoWait, ResultCode) then
      begin
      Log(Format('Error executing batch file %s to delete %s', [BatchPath, FilePath]));
      end
      else
      begin
      Log(Format('Executed batch file %s to delete %s', [BatchPath, FilePath]));
      end;
      end;
      end;





      share|improve this answer






























        2














        As suggested in other answers, you can launch a separate process at the end of the installation that will take care of the cleanup, after the installation processes finishes.



        A simple solution is creating an ad-hoc batch file that loops until the DLL file can be deleted and then also deletes the (now empty) temporary folder and itself.



        procedure DeinitializeSetup();
        var
        FilePath: string;
        BatchPath: string;
        S: TArrayOfString;
        ResultCode: Integer;
        begin
        FilePath := ExpandConstant('{tmp}MyAssembly.dll');
        if not FileExists(FilePath) then
        begin
        Log(Format('File %s does not exist', [FilePath]));
        end
        else
        begin
        BatchPath :=
        ExpandConstant('{%TEMP}') +
        'delete_' + ExtractFileName(ExpandConstant('{tmp}')) + '.bat';
        SetArrayLength(S, 7);
        S[0] := ':loop';
        S[1] := 'del "' + FilePath + '"';
        S[2] := 'if not exist "' + FilePath + '" goto end';
        S[3] := 'goto loop';
        S[4] := ':end';
        S[5] := 'rd "' + ExpandConstant('{tmp}') + '"';
        S[6] := 'del "' + BatchPath + '"';
        if not SaveStringsToFile(BatchPath, S, False) then
        begin
        Log(Format('Error creating batch file %s to delete %s', [BatchPath, FilePath]));
        end
        else
        if not Exec(BatchPath, '', '', SW_HIDE, ewNoWait, ResultCode) then
        begin
        Log(Format('Error executing batch file %s to delete %s', [BatchPath, FilePath]));
        end
        else
        begin
        Log(Format('Executed batch file %s to delete %s', [BatchPath, FilePath]));
        end;
        end;
        end;





        share|improve this answer




























          2












          2








          2







          As suggested in other answers, you can launch a separate process at the end of the installation that will take care of the cleanup, after the installation processes finishes.



          A simple solution is creating an ad-hoc batch file that loops until the DLL file can be deleted and then also deletes the (now empty) temporary folder and itself.



          procedure DeinitializeSetup();
          var
          FilePath: string;
          BatchPath: string;
          S: TArrayOfString;
          ResultCode: Integer;
          begin
          FilePath := ExpandConstant('{tmp}MyAssembly.dll');
          if not FileExists(FilePath) then
          begin
          Log(Format('File %s does not exist', [FilePath]));
          end
          else
          begin
          BatchPath :=
          ExpandConstant('{%TEMP}') +
          'delete_' + ExtractFileName(ExpandConstant('{tmp}')) + '.bat';
          SetArrayLength(S, 7);
          S[0] := ':loop';
          S[1] := 'del "' + FilePath + '"';
          S[2] := 'if not exist "' + FilePath + '" goto end';
          S[3] := 'goto loop';
          S[4] := ':end';
          S[5] := 'rd "' + ExpandConstant('{tmp}') + '"';
          S[6] := 'del "' + BatchPath + '"';
          if not SaveStringsToFile(BatchPath, S, False) then
          begin
          Log(Format('Error creating batch file %s to delete %s', [BatchPath, FilePath]));
          end
          else
          if not Exec(BatchPath, '', '', SW_HIDE, ewNoWait, ResultCode) then
          begin
          Log(Format('Error executing batch file %s to delete %s', [BatchPath, FilePath]));
          end
          else
          begin
          Log(Format('Executed batch file %s to delete %s', [BatchPath, FilePath]));
          end;
          end;
          end;





          share|improve this answer















          As suggested in other answers, you can launch a separate process at the end of the installation that will take care of the cleanup, after the installation processes finishes.



          A simple solution is creating an ad-hoc batch file that loops until the DLL file can be deleted and then also deletes the (now empty) temporary folder and itself.



          procedure DeinitializeSetup();
          var
          FilePath: string;
          BatchPath: string;
          S: TArrayOfString;
          ResultCode: Integer;
          begin
          FilePath := ExpandConstant('{tmp}MyAssembly.dll');
          if not FileExists(FilePath) then
          begin
          Log(Format('File %s does not exist', [FilePath]));
          end
          else
          begin
          BatchPath :=
          ExpandConstant('{%TEMP}') +
          'delete_' + ExtractFileName(ExpandConstant('{tmp}')) + '.bat';
          SetArrayLength(S, 7);
          S[0] := ':loop';
          S[1] := 'del "' + FilePath + '"';
          S[2] := 'if not exist "' + FilePath + '" goto end';
          S[3] := 'goto loop';
          S[4] := ':end';
          S[5] := 'rd "' + ExpandConstant('{tmp}') + '"';
          S[6] := 'del "' + BatchPath + '"';
          if not SaveStringsToFile(BatchPath, S, False) then
          begin
          Log(Format('Error creating batch file %s to delete %s', [BatchPath, FilePath]));
          end
          else
          if not Exec(BatchPath, '', '', SW_HIDE, ewNoWait, ResultCode) then
          begin
          Log(Format('Error executing batch file %s to delete %s', [BatchPath, FilePath]));
          end
          else
          begin
          Log(Format('Executed batch file %s to delete %s', [BatchPath, FilePath]));
          end;
          end;
          end;






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Feb 6 '17 at 12:17

























          answered Jan 8 '17 at 10:50









          Martin PrikrylMartin Prikryl

          86.4k22164360




          86.4k22164360

























              1














              You could add a batch script (in the form of running cmd -c) to be executed at the end of setup that waits for the file to be deletable and deletes it. (just make sure to set the inno option to not wait for the cmd process to complete)



              You could also make your installed program detect and delete it on first execution.






              share|improve this answer




























                1














                You could add a batch script (in the form of running cmd -c) to be executed at the end of setup that waits for the file to be deletable and deletes it. (just make sure to set the inno option to not wait for the cmd process to complete)



                You could also make your installed program detect and delete it on first execution.






                share|improve this answer


























                  1












                  1








                  1







                  You could add a batch script (in the form of running cmd -c) to be executed at the end of setup that waits for the file to be deletable and deletes it. (just make sure to set the inno option to not wait for the cmd process to complete)



                  You could also make your installed program detect and delete it on first execution.






                  share|improve this answer













                  You could add a batch script (in the form of running cmd -c) to be executed at the end of setup that waits for the file to be deletable and deletes it. (just make sure to set the inno option to not wait for the cmd process to complete)



                  You could also make your installed program detect and delete it on first execution.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 12 '16 at 19:09









                  Sean KSean K

                  29627




                  29627























                      1














                      As suggested in this Code Project Article : https://www.codeproject.com/kb/threads/howtodeletecurrentprocess.aspx



                      call a cmd with arguments as shown below.



                       Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " +  Application.ExecutablePath);


                      But basically as @Sean suggested, make sure you dont wait for the cmd.exe to exit in your script.






                      share|improve this answer
























                      • For this to be reliable, you have to wait for the installer process to finish. Waiting a fixed time is not hardly reliable.

                        – Martin Prikryl
                        Jan 8 '17 at 10:24
















                      1














                      As suggested in this Code Project Article : https://www.codeproject.com/kb/threads/howtodeletecurrentprocess.aspx



                      call a cmd with arguments as shown below.



                       Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " +  Application.ExecutablePath);


                      But basically as @Sean suggested, make sure you dont wait for the cmd.exe to exit in your script.






                      share|improve this answer
























                      • For this to be reliable, you have to wait for the installer process to finish. Waiting a fixed time is not hardly reliable.

                        – Martin Prikryl
                        Jan 8 '17 at 10:24














                      1












                      1








                      1







                      As suggested in this Code Project Article : https://www.codeproject.com/kb/threads/howtodeletecurrentprocess.aspx



                      call a cmd with arguments as shown below.



                       Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " +  Application.ExecutablePath);


                      But basically as @Sean suggested, make sure you dont wait for the cmd.exe to exit in your script.






                      share|improve this answer













                      As suggested in this Code Project Article : https://www.codeproject.com/kb/threads/howtodeletecurrentprocess.aspx



                      call a cmd with arguments as shown below.



                       Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " +  Application.ExecutablePath);


                      But basically as @Sean suggested, make sure you dont wait for the cmd.exe to exit in your script.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Jan 8 '17 at 2:07









                      Mohammedparvez ShaikhMohammedparvez Shaikh

                      235




                      235













                      • For this to be reliable, you have to wait for the installer process to finish. Waiting a fixed time is not hardly reliable.

                        – Martin Prikryl
                        Jan 8 '17 at 10:24



















                      • For this to be reliable, you have to wait for the installer process to finish. Waiting a fixed time is not hardly reliable.

                        – Martin Prikryl
                        Jan 8 '17 at 10:24

















                      For this to be reliable, you have to wait for the installer process to finish. Waiting a fixed time is not hardly reliable.

                      – Martin Prikryl
                      Jan 8 '17 at 10:24





                      For this to be reliable, you have to wait for the installer process to finish. Waiting a fixed time is not hardly reliable.

                      – Martin Prikryl
                      Jan 8 '17 at 10:24











                      0














                      While not exactly an answer to your question, can't you just mark the DLL to be deleted next time the computer is restarted?






                      share|improve this answer



















                      • 9





                        If I'm not mistaken, you should add this as a comment to the question itself

                        – Matías Fidemraizer
                        Feb 7 '15 at 22:19











                      • While this is a possible work-around, its not ideal, doesnt answer the question, and doesn't explain the reason that unloading the DLL fails in the first place.

                        – caesay
                        May 20 '16 at 0:38
















                      0














                      While not exactly an answer to your question, can't you just mark the DLL to be deleted next time the computer is restarted?






                      share|improve this answer



















                      • 9





                        If I'm not mistaken, you should add this as a comment to the question itself

                        – Matías Fidemraizer
                        Feb 7 '15 at 22:19











                      • While this is a possible work-around, its not ideal, doesnt answer the question, and doesn't explain the reason that unloading the DLL fails in the first place.

                        – caesay
                        May 20 '16 at 0:38














                      0












                      0








                      0







                      While not exactly an answer to your question, can't you just mark the DLL to be deleted next time the computer is restarted?






                      share|improve this answer













                      While not exactly an answer to your question, can't you just mark the DLL to be deleted next time the computer is restarted?







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Feb 7 '15 at 22:19









                      zmbqzmbq

                      29.1k961123




                      29.1k961123








                      • 9





                        If I'm not mistaken, you should add this as a comment to the question itself

                        – Matías Fidemraizer
                        Feb 7 '15 at 22:19











                      • While this is a possible work-around, its not ideal, doesnt answer the question, and doesn't explain the reason that unloading the DLL fails in the first place.

                        – caesay
                        May 20 '16 at 0:38














                      • 9





                        If I'm not mistaken, you should add this as a comment to the question itself

                        – Matías Fidemraizer
                        Feb 7 '15 at 22:19











                      • While this is a possible work-around, its not ideal, doesnt answer the question, and doesn't explain the reason that unloading the DLL fails in the first place.

                        – caesay
                        May 20 '16 at 0:38








                      9




                      9





                      If I'm not mistaken, you should add this as a comment to the question itself

                      – Matías Fidemraizer
                      Feb 7 '15 at 22:19





                      If I'm not mistaken, you should add this as a comment to the question itself

                      – Matías Fidemraizer
                      Feb 7 '15 at 22:19













                      While this is a possible work-around, its not ideal, doesnt answer the question, and doesn't explain the reason that unloading the DLL fails in the first place.

                      – caesay
                      May 20 '16 at 0:38





                      While this is a possible work-around, its not ideal, doesnt answer the question, and doesn't explain the reason that unloading the DLL fails in the first place.

                      – caesay
                      May 20 '16 at 0:38











                      -1














                      The easy way to do what you want is through an AppDomain. You can unload an AppDomain, just not the initial one. So the solution is to create a new AppDomain, load your managed DLL in that and then unload the AppDomain.



                              AppDomain ad = AppDomain.CreateDomain("Isolate DLL");
                      Assembly a = ad.Load(new AssemblyName("MyManagedDll"));
                      object d = a.CreateInstance("MyManagedDll.MyManagedClass");
                      Type t = d.GetType();
                      double result = (double)t.InvokeMember("Calculate", BindingFlags.InvokeMethod, null, d, new object { 1.0, 2.0 });
                      AppDomain.Unload(ad);


                      Here is what the DLL code looks like...



                      namespace MyManagedDll
                      {
                      public class MyManagedClass
                      {
                      public double Calculate(double a, double b)
                      {
                      return a + b;
                      }
                      }
                      }





                      share|improve this answer



















                      • 1





                        That's irrelevant to the OP. The OP wants to implement an extension to an existing unmanaged application in .NET. OP cannot create new AppDomain, as he/she does not control the DLL loading process.

                        – Martin Prikryl
                        Feb 13 '17 at 19:26













                      • It is indeed relevant. He can get to a managed DLL. That managed DLL simply creates an App Domain and loads another managed DLL which is then unloaded. So what was missing from my answer is that 2 managed DLLs would be required. I simply thought that was obvious.

                        – AQuirky
                        Feb 14 '17 at 19:45











                      • Yes it was obvious. But the problem the OP has is: "The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive." - That your answer cannot solve that problem.

                        – Martin Prikryl
                        Feb 14 '17 at 19:59


















                      -1














                      The easy way to do what you want is through an AppDomain. You can unload an AppDomain, just not the initial one. So the solution is to create a new AppDomain, load your managed DLL in that and then unload the AppDomain.



                              AppDomain ad = AppDomain.CreateDomain("Isolate DLL");
                      Assembly a = ad.Load(new AssemblyName("MyManagedDll"));
                      object d = a.CreateInstance("MyManagedDll.MyManagedClass");
                      Type t = d.GetType();
                      double result = (double)t.InvokeMember("Calculate", BindingFlags.InvokeMethod, null, d, new object { 1.0, 2.0 });
                      AppDomain.Unload(ad);


                      Here is what the DLL code looks like...



                      namespace MyManagedDll
                      {
                      public class MyManagedClass
                      {
                      public double Calculate(double a, double b)
                      {
                      return a + b;
                      }
                      }
                      }





                      share|improve this answer



















                      • 1





                        That's irrelevant to the OP. The OP wants to implement an extension to an existing unmanaged application in .NET. OP cannot create new AppDomain, as he/she does not control the DLL loading process.

                        – Martin Prikryl
                        Feb 13 '17 at 19:26













                      • It is indeed relevant. He can get to a managed DLL. That managed DLL simply creates an App Domain and loads another managed DLL which is then unloaded. So what was missing from my answer is that 2 managed DLLs would be required. I simply thought that was obvious.

                        – AQuirky
                        Feb 14 '17 at 19:45











                      • Yes it was obvious. But the problem the OP has is: "The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive." - That your answer cannot solve that problem.

                        – Martin Prikryl
                        Feb 14 '17 at 19:59
















                      -1












                      -1








                      -1







                      The easy way to do what you want is through an AppDomain. You can unload an AppDomain, just not the initial one. So the solution is to create a new AppDomain, load your managed DLL in that and then unload the AppDomain.



                              AppDomain ad = AppDomain.CreateDomain("Isolate DLL");
                      Assembly a = ad.Load(new AssemblyName("MyManagedDll"));
                      object d = a.CreateInstance("MyManagedDll.MyManagedClass");
                      Type t = d.GetType();
                      double result = (double)t.InvokeMember("Calculate", BindingFlags.InvokeMethod, null, d, new object { 1.0, 2.0 });
                      AppDomain.Unload(ad);


                      Here is what the DLL code looks like...



                      namespace MyManagedDll
                      {
                      public class MyManagedClass
                      {
                      public double Calculate(double a, double b)
                      {
                      return a + b;
                      }
                      }
                      }





                      share|improve this answer













                      The easy way to do what you want is through an AppDomain. You can unload an AppDomain, just not the initial one. So the solution is to create a new AppDomain, load your managed DLL in that and then unload the AppDomain.



                              AppDomain ad = AppDomain.CreateDomain("Isolate DLL");
                      Assembly a = ad.Load(new AssemblyName("MyManagedDll"));
                      object d = a.CreateInstance("MyManagedDll.MyManagedClass");
                      Type t = d.GetType();
                      double result = (double)t.InvokeMember("Calculate", BindingFlags.InvokeMethod, null, d, new object { 1.0, 2.0 });
                      AppDomain.Unload(ad);


                      Here is what the DLL code looks like...



                      namespace MyManagedDll
                      {
                      public class MyManagedClass
                      {
                      public double Calculate(double a, double b)
                      {
                      return a + b;
                      }
                      }
                      }






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Feb 13 '17 at 19:03









                      AQuirkyAQuirky

                      2,0051821




                      2,0051821








                      • 1





                        That's irrelevant to the OP. The OP wants to implement an extension to an existing unmanaged application in .NET. OP cannot create new AppDomain, as he/she does not control the DLL loading process.

                        – Martin Prikryl
                        Feb 13 '17 at 19:26













                      • It is indeed relevant. He can get to a managed DLL. That managed DLL simply creates an App Domain and loads another managed DLL which is then unloaded. So what was missing from my answer is that 2 managed DLLs would be required. I simply thought that was obvious.

                        – AQuirky
                        Feb 14 '17 at 19:45











                      • Yes it was obvious. But the problem the OP has is: "The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive." - That your answer cannot solve that problem.

                        – Martin Prikryl
                        Feb 14 '17 at 19:59
















                      • 1





                        That's irrelevant to the OP. The OP wants to implement an extension to an existing unmanaged application in .NET. OP cannot create new AppDomain, as he/she does not control the DLL loading process.

                        – Martin Prikryl
                        Feb 13 '17 at 19:26













                      • It is indeed relevant. He can get to a managed DLL. That managed DLL simply creates an App Domain and loads another managed DLL which is then unloaded. So what was missing from my answer is that 2 managed DLLs would be required. I simply thought that was obvious.

                        – AQuirky
                        Feb 14 '17 at 19:45











                      • Yes it was obvious. But the problem the OP has is: "The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive." - That your answer cannot solve that problem.

                        – Martin Prikryl
                        Feb 14 '17 at 19:59










                      1




                      1





                      That's irrelevant to the OP. The OP wants to implement an extension to an existing unmanaged application in .NET. OP cannot create new AppDomain, as he/she does not control the DLL loading process.

                      – Martin Prikryl
                      Feb 13 '17 at 19:26







                      That's irrelevant to the OP. The OP wants to implement an extension to an existing unmanaged application in .NET. OP cannot create new AppDomain, as he/she does not control the DLL loading process.

                      – Martin Prikryl
                      Feb 13 '17 at 19:26















                      It is indeed relevant. He can get to a managed DLL. That managed DLL simply creates an App Domain and loads another managed DLL which is then unloaded. So what was missing from my answer is that 2 managed DLLs would be required. I simply thought that was obvious.

                      – AQuirky
                      Feb 14 '17 at 19:45





                      It is indeed relevant. He can get to a managed DLL. That managed DLL simply creates an App Domain and loads another managed DLL which is then unloaded. So what was missing from my answer is that 2 managed DLLs would be required. I simply thought that was obvious.

                      – AQuirky
                      Feb 14 '17 at 19:45













                      Yes it was obvious. But the problem the OP has is: "The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive." - That your answer cannot solve that problem.

                      – Martin Prikryl
                      Feb 14 '17 at 19:59







                      Yes it was obvious. But the problem the OP has is: "The DLL can't seem to be unloaded anymore. Using Inno-Setup's UnloadDLL(...) has no effect and the file remains locked until the installer exits. Because of this, the setup waits for 2 seconds and then fails to delete my DLL file from the temp directory (or install directory). In fact, it really stays there until somebody cleans up the drive." - That your answer cannot solve that problem.

                      – Martin Prikryl
                      Feb 14 '17 at 19:59




















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f28388095%2funload-a-net-dll-from-an-unmanaged-process%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Costa Masnaga

                      Fotorealismo

                      Sidney Franklin