Skip to content
⌘ NSIS Forum Archive

GetBinaryType

20 posts

roonwhit#

GetBinaryType

I'm not a C programmer, so I'm having problems getting the kernel32::GetBinaryType call correct. I need to know whether Excel is 63-bit or 32-bit. I am reading the install location from registry, and then trying:
System::Call "kernel32::GetBinaryType(t r0, *l .r1)"
where $0 contains the full path and filename for excel.exe
(Argument types are LPCTSTR and LPDWORD, with the return BOOL, which I'm ignoring).

I have tried various combinations of variables to get the type back, but to no avail. I have written a Fortran executable that runs properly, but it would be much neater if it was in the script.
Thanks for any assistance.
JasonFriday13#
Because that function requires a pointer, you have to allocate enough bytes to store the data. So the required data for the result is a DWORD, which is 4 bytes. Then you have to extract the data from the pointer, then free the pointer.

Reference: http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

Here's a quick example I wrote, this returns '0' for 32 bit makensisw, and '6' for 64 bit makensisw.

Name "GetBinaryType test"
OutFile "GetBinaryType.exe"

RequestExecutionLevel User
ShowInstDetails Show

Page InstFiles

Section

;StrCpy $0 "C:\Program Files XP\NSIS\makensisw.exe"
StrCpy $0 "C:\x64NSIS_test\NSIS\makensisw.exe"

System::Alloc 4 ; Alloc 4 bytes for the function.
Pop $1
System::Call 'kernel32::GetBinaryType(t r0, i r1)'
System::Call '*$1(i .r2)' ; Extract the data.
System::Free $1

DetailPrint "Value of $$2: $2"

SectionEnd
Afrow UK#
Originally Posted by JasonFriday13 View Post
Because that function requires a pointer, you have to allocate enough bytes to store the data. So the required data for the result is a DWORD, which is 4 bytes. Then you have to extract the data from the pointer, then free the pointer.

Reference: http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

Here's a quick example I wrote, this returns '0' for 32 bit makensisw, and '6' for 64 bit makensisw.
You don't need to allocate anything:
System::Call `kernel32::GetBinaryType(t 'C:\Windows\SysNative\Notepad.exe', *i .R0)`
Stu
JasonFriday13#
Cool, there's two different ways to do the same task 😎. I haven't used the system plugin in ages and I don't know about that shortcut.
Anders#
Originally Posted by JasonFriday13 View Post
Cool, there's two different ways to do the same task 😎. I haven't used the system plugin in ages and I don't know about that shortcut.
The pointer flag * only works for i, l and p and exists because some functions return DWORDs or pointers in some parameters. v3 beta1 supports the new @ syntax so you can return into a buffer up to about 1000 bytes without using System::Alloc as long as the parameter is out only.
roonwhit#
I get a return value of 0 for both 32 and 64 bit exe files. Using *i doesn't make any difference.

Thx David
Afrow UK#
Originally Posted by roonwhit View Post
I get a return value of 0 for both 32 and 64 bit exe files. Using *i doesn't make any difference.

Thx David
Have you tried my code? It returns 6 for me.

Stu
roonwhit#
Stu,

I don't have a SysNative folder, but calling to Notepad is Windows is not returning any value.

David
JasonFriday13#
Alright, try this. I've added an attachment with a test script. Extract to a folder, compile and run it. Then paste up the result here. Running this gives me:
makensisw-x86.exe(0)=|0|
makensisw-amd64.exe(6)=|6|
Completed
roonwhit#
Stu,

That works fine on my home computer ... will have to wait until tomorrow to check at work.
Thanks,
David
Afrow UK#
If you are using the System32 path (e.g. $SYSDIR) for notepad.exe then GetBinaryType will always return 0. This is because the NSIS installer always gets the 32-bit binary path due to WOW64 file system redirection (NSIS is 32-bit). So either use SysNative or use the preferred method - disable WOW64 file system redirection using the ${DisableX64FSRedirection} macro in x64.nsh.

Stu
Anders#
Originally Posted by Afrow UK View Post
So either use SysNative or use the preferred method - disable WOW64 file system redirection using the ${DisableX64FSRedirection} macro in x64.nsh.
${DisableX64FSRedirection} is not always safe to use around a System::Call. There are at least three possible issues:

1) System::Call will call LoadLibrary on the specified module and this can fail if the module is not already loaded. Not a issue in this case since kernel32 is always loaded.

2) The function you are calling might load a library (delay loading, shell extensions etc). This can often happen when you are dealing with shell stuff (pidls/IShellFolder etc)

3) The function you are calling might use ImageHlp/DbgHelp or otherwise call LoadLibrary to parse a input file. We don't know how GetBinaryType works internally but since MSDN states that it supports \\?\ long paths we can hope that it just uses CreateFile.
roonwhit#
Jason,

Your code works perfectly on my machine at home, but at work, both files return 0.

So something about NSIS on my machine at work is broken! I'm using HM NIS Edit Portable.

David
roonwhit#
Installed 3.0b1 - scripts now correctly return expected values, both for Jason's code and my original ones. So issue was bug in version of compiler installed with Portable Apps version of HM NIS Edit.

Sorry for the distraction.
David
JasonFriday13#
No problem 👍. When there's a problem, there is no such thing as a distraction. We tested through it and fixed it 😎.
Anders#
Originally Posted by roonwhit View Post
Installed 3.0b1 - scripts now correctly return expected values, both for Jason's code and my original ones. So issue was bug in version of compiler installed with Portable Apps version of HM NIS Edit.
Is the portable version using the NSIS fork from scratchpaper.com (2.46.xyz)? It has issues with calling functions that are exported 3 times (some functions in kernel32 and shell32 are exported as plain and with A and W suffix)
roonwhit#
I don't know about scratchpaper.com, but it is 2.46.5 Rev 2.
I have installed 3.0b1, which solves the problem, although I would prefer a portable version due to managed client restrictions at work.
JasonFriday13#
Originally Posted by roonwhit View Post
I don't know about scratchpaper.com, but it is 2.46.5 Rev 2.
That version number is the same as the one from scratchpaper.com, which is unicode only.

NSIS 3 basically merges ansi and unicode together, no doubt PortableApps will update it once NSIS 3 hits mainstream (could be a while though).
Anders#
Originally Posted by roonwhit View Post
I don't know about scratchpaper.com, but it is 2.46.5 Rev 2.
I have installed 3.0b1, which solves the problem, although I would prefer a portable version due to managed client restrictions at work.
Portable apps from portableapps.com are not self contained AFAIK, that is, they can leave junk behind after running. Anyway, MakensisW will write a couple of entries in the registry but the compiler itself will not write anything anywhere so you can just install 3.0 at home, put it in a zip file and use that as your portable version...