WINAMP.COM | Forums > Developer Center > NSIS Discussion > Calling managed .NET DLL from NSIS - this works :-) |
| Pages (3): [1] 2 3 » |
Last Thread
Next Thread
|
| Author |
|
|
Afrow UK Moderator
Registered: Nov 2002 |
Nice! Please could you make a Wiki page for this? __________________ |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Done. It is now located here: |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
I justed tested my installer on a system with no .NET framework at all, and it seems I have to make sure that both the .NET framework and Visual C++ redistributable are installed. I'm gonna write this into the wiki. |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Forget that. I found it to be something else. Basically it is because the cannot find the C# dll when calling it via the C++ dll. I will work on it and get back when I have the solution. |
||
|
|
|
Afrow UK Moderator
Registered: Nov 2002 |
Try setting the current directory to $PLUGINSDIR with SetOutPath. If that doesn't work you could try updating the PATH variable to point to $PLUGINSDIR. Maybe it would be easier just to extract the C# dll to $SYSDIR. __________________ |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Unfortunately none of those three method works, I tried them. It would have been nice. I will explain at the bottom of this post why and some details, but here is a workaround, that will work: |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
I have work in progress 3) It can handle string parameters and string return value at the moment. Todo: Dynamic number of parameters. Todo: Object type return value. Todo: Fix a bug where that causes the DLL to remain in the tmp directory. NSIS can't delete it. I also have it in a version, where you call it with System::Call, and this version does not remain in the tmp directory. This version has to be included manually in the installer and placed in for instance $PLUGINSDIR. It is called with (one line): Both versions are attached. If you want to try it, remember to rename the desired DLL to CLRLoader.dll. If it is the "native" NSIS version, put it in the pluginsdir. |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
My new NSIS plug-in is now working. It can call methods in managed .NET DLLs. It supports dynamic number of parameters of types void, string (unicode), int, float, bool. Return value can be these types too. Strings and floats must be enclosed in "". The .NET classes called must have a default constructor. This replaces the above method I described and my former wiki, as this plug-in fixes some issues with the method described previously. Regards Claes P.S.: Minor issue: You have to call it via System::Call. While this works perfectly, I would like it to be a true NSIS plugin. The reason for why it is called via System::Call is that if I make it a real NSIS plugin, the DLL remains in the $PLUGINS dir when the installer closes. If I get to fix that issue, I can make it a real NSIS plugin, that does not need System::Call. Last edited by claesabrandt on 08-18-2008 at 12:22 PM |
||
|
|
|
Afrow UK Moderator
Registered: Nov 2002 |
You can use `` for outer quotes saving you having to use $\" for ". __________________ |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Excellent, thanks |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Stu, I have a question. I really would like this to be a native NSIS dll, but as stated, the dll will not be deleted by NSIS, when the installer closes. I found out that it is automatically marked by NSIS to be deleted along with the directory, on next reboot, and so the file is gone. My question is, would that be ok? Or should I for now stick to the version where I call it with System::Call? The call would be much cleaner, if I made it a native NSIS plugin, and I probably would devide the parameters up into different parts. And the user would not have to include it manually, just put it in the plugins dir. |
||
|
|
|
Afrow UK Moderator
Registered: Nov 2002 |
Sure keep as both and let the user decide which to use. __________________ |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Stu, would it be possible to remove the zip file from post #8, as it seems some have downloadet that instead of the zip in post #9. The zip in post #8 should not be used. |
||
|
|
|
Afrow UK Moderator
Registered: Nov 2002 |
Sorry I just deleted the wrong one. Either way it would be best to upload to the Wiki instead. __________________ |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
New wiki page including download
No problem |
||
|
|
|
Afrow UK Moderator
Registered: Nov 2002 |
I noticed your float has a comma in it rather than a full stop in the sample code. __________________ |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Yes, in Denmark we use a comma there. I know that you use dot in UK and US, so I will correct the sample. However, I am working on another way to pass in parameters (using variable arguments in c++), which will eliminate the problem. |
||
|
|
|
rbchasetfb Junior Member
Registered: Sep 2008 |
Love the CLRLoader...did just what I needed. However, is there a trick to get the CLRLoader.dll to delete from the $PLUGINSDIR when the NSIS Setup ends. All the other DLLs and files delete okay, including the one that CLRLoader calls, just the CLRLoader.dll is left behind. Here's the code snipet: Thanks in Advance for the help. |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Yes, it is a known issue. I am working on how to fix it, but for now you just have to leave it as is. The file is deleted the next time the user reboots the system. Did you use the new plug-in located at http://nsis.sourceforge.net/Call_.NET_DLL_methods_plug-in, or did you you one of the previous versions? |
||
|
|
|
rbchasetfb Junior Member
Registered: Sep 2008 |
Thanks for the quick reply. I did get the one from that link. I found that I could delete CLRLoader.dll right after the NSIS installer closed and not have to wait for the reboot. |
||
|
|
|
LoRd_MuldeR Senior Member
Registered: Sep 2005 |
Just one question: Is there a specific reason why your "CLR.dll" must be called through the System-Plugin instead of making it a "normal" NSIS plugin? This way the parameters could be passed to the CLR plugin directly, instead of wrapping them into the System plugin parameters. Like this: code: __________________ |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
There is no reason anymore, and I will soon replace it with a native NSIS plugin. |
||
|
|
|
LoRd_MuldeR Senior Member
Registered: Sep 2005 |
I don't think NSIS does support Unicode yet. But there is development going into that direction. However I think the strings passed from NSIS to the System-Plugin are *not* Unicode, so passing the None-Unicode strings directly from NSIS to your CLR-Plugin should be no worse at least... code: __________________ |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Alright. I have uploaded a new version of the plugin, version 0.2. It is now a native NSIS plugin |
||
|
|
|
LoRd_MuldeR Senior Member
Registered: Sep 2005 |
code: code: __________________ |
||
|
|
|
rbchasetfb Junior Member
Registered: Sep 2008 |
Thanks for the speedy update, claesabrandt. I've downloaded and tried your example, but when I call pop $0 after CLR:Call, $0 contains the name of my DLL. If I call pop $0 again, it contains the "Namespace.Classname" parameter. I'm probably missing something, but I did use the testscript.nsi you included, just don't seem to be able to get the return string in $0. |
||
|
|
|
LoRd_MuldeR Senior Member
Registered: Sep 2005 |
Returning a value could also be "optimized" with a macro: code: code: __________________ |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
rbchasetfb, I had the same problem, but then I found out that I still was compiling the old CLR.dll with the installer. Make sure no CLR.dll is located in the script's directory and that you do not call File CLR.dll. Just put the CLR.dll in NSIS's plugins dir. Let me know if it helps. |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Just corrected a bug where if more that one class were found in the .net assembly, only the first class could be loaded. Version 0.3 can be downloaded now and the wiki has been updated. |
||
|
|
|
rbchasetfb Junior Member
Registered: Sep 2008 |
Ok. Here's the latest. |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
That is really strange. I'm already compiling it for .NET framework 2.0, just using VS2008 to do it. I cannot reproduce the error at all |
||
|
|
|
rbchasetfb Junior Member
Registered: Sep 2008 |
claesabrandt, I think I fixed the need for passing the number of parameters. In the Call function in your code, replace the num params and params sections with the following code and add the itreplace function above the Call function in the code. Basically, this code performs a split function on the string popped of the stack and adds each split-off element to the args vector, performing a replace of the single quotes along the way. Here's the itreplace function: Then, in the NSIS project, do the plugin call this way: OR...the code has the provision to do it this way with single quotes around strings to be visually clean: You can also leave the spaces out after the commas in the parameter list if you like. On the issue of the strange results from my test scenario's I wrote about earlier, I've even tried the tests on other machines and get the same results. My last test runthrough was on a Windows 2003 Server with only .net 2.0 installed. For now, I'll live with the stay-behind dll file and use the VS2005 compiled one with the changes above. Thanks again. Let me know if you find any bugs in the above code. |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Thanks for the reply, it is nice to have other eyes on this, I appreciate your help Last edited by claesabrandt on 09-04-2008 at 05:01 PM |
||
|
|
|
rbchasetfb Junior Member
Registered: Sep 2008 |
Okay, maybe on to something here. That return value being the dll name problem seems to stem from the version of .NET installed. |
||
|
|
|
rbchasetfb Junior Member
Registered: Sep 2008 |
claesabrandt, can you check the file version of you System.dll in the C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 folder. Mine reads 2.0.50727.1433. It seems that the .1433 build number is the important part, when its .42, my VS2005 build doesn't work (dll calls return the dll filename). |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Mine reads 2.0.50727.1433 as yours. Now that you mention this, I have a vmware machine where my plugin sometimes returns a bogus value. I will investigate too, but it sounds like the stack is getting messed up in some way. |
||
|
|
|
rbchasetfb Junior Member
Registered: Sep 2008 |
I was thinking it might read something differently entirely on your machine than .1433, .42 or .3053. So it would seem that that is not it. I'm at a loss on this issue as neither of us are able to both compile the same CLR.dll and subsequently recreate the problem. |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Hmm, I just tried it on my vwmare machine, and on that System.dll has the same version 2.0.50727.1433. Here the call actually fails and has the same result as you experienced - it returns the name of the dll file. Don't worry, we will eventually find the problem |
||
|
|
|
claesabrandt Member
Registered: Aug 2008 |
Wait, it seems the problem is completely different. NSIS actually outputs the error "Could not load "..blabla..CLR.dll". However, the DLL has been copied by NSIS to the correct location, so it is some load error. |
||
|
|
|
| Pages (3): [1] 2 3 » |
Last Thread Next Thread
|
WINAMP.COM | Forums > Developer Center > NSIS Discussion > Calling managed .NET DLL from NSIS - this works :-) |
Forum Rules:
|