gianlucav
1st October 2010 01:20 UTC
How to call System::Call with an absolute DLL path
Hi.
I have an installer that does this:
SetOutPath $INSTDIR
System::Call 'MyDll::MyFunction(t, i) i("","w").r0 ? u'
The problem is that MyDll.dll is loaded from the current directory (probably using LoadLibrary with a relative path) and this breaks when this KB from MS in installed:
http://support.microsoft.com/kb/2264107
The current directory is removed from the DLL search path and System::Call fails.
The solution is probably to use an absolute path. How to I pass an absolute path to System::Call?
Animaether
1st October 2010 07:05 UTC
you just... do?
System
::Call "some.dll:someFunction(parameters)"
becomes
System
::Call "DRIVE:\folder\subfolder\etc\some.dll:someFunction(parameters)"
gianlucav
1st October 2010 17:22 UTC
If the path contains parentheses, the call fails. This is for example the case when the path is c:\program files (x86)\.... (x86 application installed on x64 Windows)
I think System::Call interprets the parenthesis in (x86) as the beginning of the parameters.
MSG
1st October 2010 17:49 UTC
Ok, so how about just adding some quotes then?
System::Call '"DRIVE:\folder\subfolder\etc\some.dll":someFunction(parameters)'
Animaether
1st October 2010 17:56 UTC
hmmm... sounds like a bug.. 'll drop that in the bug tracker later
In the mean time.. hum... work-arounds.. work-arounds..
putting quotes around it doesn't help... sticking the path in a variable and using that doesn't help...
Here's one method that should work - but I admit readily that it kinda sucks...
System
::Call "kernel32::LoadLibrary(t 'c:\path\to\your.dll') i .r0"
System::Call "kernel32::GetProcAddress(i r0, t 'ExportedFunction') i .r1"
System::Call "::$1(the usual parameters here)"
System::Call "kernel32::FreeLibrary(i r0)"
might have to call 'kernel32::FreeLibrary $0'.. that tended to crash on the DLL I was testing with, though.. can't say I know 100% for sure that FreeLibrary() is required ( I guess the reference count dies on installer exit anyway, and the DLL doesn't appear to be locked )
Edit: FreeLibrary() should indeed be used.. must be the test DLL.
Animaether
1st October 2010 18:18 UTC
Looks like the devs are aware of the issue, at least on some level... Bug 1616267 applies readily. You already tried the suggestion therein (using SetOutpath). I'll add a comment to that bug as kichik notes in it that parentheses are indeed problematic.