Unload a .NET DLL from an unmanaged process
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
|
show 2 more comments
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
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
|
show 2 more comments
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
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
c# .net com inno-setup unmanaged
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
|
show 2 more comments
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
|
show 2 more comments
5 Answers
5
active
oldest
votes
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;
add a comment |
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.
add a comment |
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.
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
add a comment |
While not exactly an answer to your question, can't you just mark the DLL to be deleted next time the computer is restarted?
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
add a comment |
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;
}
}
}
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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;
add a comment |
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;
add a comment |
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;
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;
edited Feb 6 '17 at 12:17
answered Jan 8 '17 at 10:50
Martin PrikrylMartin Prikryl
86.4k22164360
86.4k22164360
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 12 '16 at 19:09
Sean KSean K
29627
29627
add a comment |
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
While not exactly an answer to your question, can't you just mark the DLL to be deleted next time the computer is restarted?
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
add a comment |
While not exactly an answer to your question, can't you just mark the DLL to be deleted next time the computer is restarted?
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
add a comment |
While not exactly an answer to your question, can't you just mark the DLL to be deleted next time the computer is restarted?
While not exactly an answer to your question, can't you just mark the DLL to be deleted next time the computer is restarted?
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
add a comment |
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
add a comment |
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;
}
}
}
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
add a comment |
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;
}
}
}
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
add a comment |
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;
}
}
}
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;
}
}
}
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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