Accepting hex values from commandline in msi installer - installshield

I am creating a msi installer using InstallShield 2015, I need to pass a hex value to the installer via command line as given below
msiexec /i setup.msi LCID=0x9
This LCID will get written into the registry in a DWORD type variable. However, I noticed that it will work only if i pass a decimal. Is there any way I can pass a hex value to the installer and write into the registry?

The public property(LCID) passed from command-line accepts parameter as string/integer only. In registry configuration, you must have defined DWORD value whose data is [LCID]. By default, the value passed from command-line will be converted to hex while being saved in registry as it's type is DWORD. In your case, hex is passed from command-line and it can't be converted to hex as per default behavior.
If you still want this behavior for this specific registry, i would recommend managed code custom action which will accepts command-line input and create registry as you want.

Related

How to read command line parameter in InstallShield script

Suppose I run my installer like this:
setup.exe /v"PARAMETER=Value"
How can I read PARAMETER? The documentation proposes to use GetProfString and GetProfInt, but which folder should I use?
For me the folders for setup.ini were I thought parameters would go are as follows:
ENGINECOMMONDIR
ENGINEDIR
C:\Users\user_name\AppData\Local\Temp\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
SRCDIR
C:\Users\user_name\AppData\Local\Temp\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\Disk1
But instead one needs to use system string variable CMDLINE.
Your reference to CMDLINE suggests you are using an InstallScript or InstallScript MSI project, which is populated through the /z notation to its setup.exe.
The /v"PARAMETER=Value" notation applies to the setup.exe used for Windows Installer projects, passing PARAMETER=Value to Windows Installer, which in turns sets the Windows Installer property PARAMETER to Value. The way to read it depends on the context in which you need it, but typically involves either a formatted text field including a reference to the property (e.g. [PARAMETER]), or code that retrieves a property through e.g. MsiGetProperty(hInstall, L"PARAMETER", buf, bufsize) (C++) or Session.Property("PARAMETER") (VB).

Calling WriteRegMultiStr in NSIS properly

With version 3.02 of NSIS came the addition of the WriteRegMultiStr function. When the function is called in my script the script throws an error:
Usage: WriteRegMultiStr /REGEDIT5 rootkey subkey entry_name hex_string_like_660000000000
root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)
The call itself looks like this:
WriteRegMultiStr /REGEDIT5 HKLM "System\CurrentControlSet\Services\SomeService" "DependsOnService" "service1 service2"
Since there is no documentation on this specific function which was added later on, long after WriteRegStr and WriteRegDWORD were available, I have to wonder - how does one use it?
So far with respect to entering REG_MULTI_SZ values I only found the directive to use a registry-NSIS -plugin. Yet the function exists, so how can it be used?
Addendum:
Encoding the string to hex and passing it with ot without quotation marks yields no desirable result either.
I was actually able to find an answer after digging through the depths of the internet. Since I don't think this has been answered on StackOverflow I will leave a response here, in case anyone wants to use this function.
The structure of the command as described in the opening post is basically correct, but the value must be encoded precisely. My command looks like this:
WriteRegMultiStr /REGEDIT5 HKLM "System\CurrentControlSet\Services\SomeService" "DependsOnService" 54,00,63,00,70,00,69,00,70,00,00,00,41,00,66,00,64
For anyone intending to test this string, this is
Tcpip
Afd
encoded in hexadecimal regedit format. Precisely this is Regedit Version 5.0 format, as opposed to REGEDIT4 format. A conversion editor can be used to achieve this, I used OTConvertIt.
The script should then compile, assuming you run NSIS version 3.02 or higher.
As you found out, the value data must be in the exact same format as .reg files from Windows 2000+.
The reason this instruction works this way is because it is actually the same as WriteRegBin under the hood and very little code was added to support this new functionality.
In the future you might be able to drop the /REGEDIT5 switch and give it plain strings but support for that has not been added yet.
The Registry plug-in does allow you to write these strings in a sane manner.

Inno Setup Reading a Registry Gives Empty String

I am a bit new to Inno Setup so spare me if this question sounds childish. Let me show you the code first:
RegQueryStringValue(HKEY_LOCAL_MACHINE,'SOFTWARE\Altera Corporation\Quartus','Quartus Version',QR_ver);
Result := True;
QR_ver should contain the value that is inside the 'Quartus Version' but instead it returns an empty string. And yes I checked 'Quartus Version' is not empty itself. It contains a value '14.0'
Please Help
My crystal ball tells me that you are on a 64-bit system and thus you have verified that value in 64-bit regedit. If that is so, use HKLM64 root key instead of HKEY_LOCAL_MACHINE. Default regedit on 64-bit system is 64-bit and shows 64-bit view on registry (32-bit view shows under the Wow6432Node node). Inno Setup maps (by default) to 32-bit view and thus you couldn't read it. – (Credits: TLama)

In Visual C++ is there a way to stop Registry redirection from transforming system32 to syswow64?

I have written a program in Visual C++ that checks a particular reg_expand_sz value in the registry for changes. The default value is %SystemRoot%\System32\NOTEPAD.EXE. If the value is changed, the program will reset it back to the default data. The keys that I am modifying are either shared or reflected depending on the version of Windows, so it doesn't matter what Registry view (32-bit or 64-bit) I modify, as the keys will be synched up.
My problem that I am having is that if I am on a 64-bit version of Windows and use a 32-bit version of the program to change the value's data to %SystemRoot%\System32\NOTEPAD.EXE, due to the Registry redirection the data will instead be saved as %SystemRoot%\SysWOW64\Notepad.exe. This is not the correct default data though. If I compile the program in 64-bit, it works as expected. I would rather, though, if possible have a single 32-bit version that could reset the defaults regardless of whether the OS is 32-bit or 64-bit.
Does anyone know of a way to disable this transformation of System32 to SysWOW64 in reg_sz/reg_expand_sz values or know another method that I can use to achieve this task? I could write out a registry file and use system() to to execute reg or regedit and import it, but would rather do everything within the confines of the program itself.
Below is my current code:
HKEY hKey;
DWORD size;
LONG lResults;
wchar_t szVdata[] = L"%SystemRoot%\\System32\\NOTEPAD.EXE %1";
size = sizeof(szVdata);
lResults = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Classes\\batfile\\shell\\edit\\command",0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey);
if(lResults == ERROR_SUCCESS)
RegSetValueExW (hKey, L"",0, REG_EXPAND_SZ, (PBYTE)szVdata, size);
RegCloseKey (hKey);
Any help would be appreciated.
Try %SystemRoot%\\SysNative\\

Return value of c# exe with exec

i have a problem using inno setup. I'm installing an update with inno, and with the update.exe the user get a txtfile with a licencenumber. On his Unit this licencenumber readable by a dll function.
Before the installingprocess i have to compare these numbers. Only if this numbers are identical the user is trying to installing the update on the right machine with the right licence.
If i would put this check into an seperate exe, it would be easy to crack it by change the exe with one just doing nothing (no errorcode). So i want to split the checking into the seperated exe (where i check some other things like installed version number etc.) and the update.exe
In update exe, i want to read the txtfile inside the updatepackage - this is easy.
In check.exe i want to call the internal dll and get the licencenumber of the machine. I have to return this number as an int. C# allows me to do that.
But how can i get this number in innosetup?
I tried to take the errorcode for this (0=error - not right version etc, XXXXXXXXX = licencenumber of machine). But the errorcode is just 2 chars in inno. I get only 2 chars...
Saving the number in another file would'nt be a solution cause the user can crack it this way... Is it possible to get the number into inno without giving the user the chance to manilpulate??
If you move the code into a DLL (either COM or a plain stdcall DLL) then it can be used by Inno and pass extra data between them including full strings, etc.

Resources