Inno Setup Reading a Registry Gives Empty String - inno-setup

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)

Related

Inno-Setup checking file location prior to installation, then using it during installation

I need to check for the location of a file during program installation utilizing inno setup. I then need inno setup to use the location of that file in the "Filename" line to create a desktop ICON for program initialization. I have the code for the "Icons" option working fine with the exception of how to do the above.
Here is the line of code I am currently using;
Name: "{commondesktop}\SA - NH Bricscad V12"; Filename:"**c:\program files\septic assistant\new hampshire\support\**SA - NH Bricscad V12.exe"; IconFilename: "C:\Program Files\Septic Assistant\New Hampshire\Support\Bricscadlogo.ico"; Comment: "Septic Assistant the only Septic Design Program"
Hi-Lited section would be the path to the exe file that I need inno setup to search for.
Any assistance with this would be very much appreciated.
Bruce
Just use a {code:...} constant and corresponding [Code] function that returns the appropriate path for your [Icons] entry. You will probably also want to use a Check function to avoid installing the icon in the case that you cannot find the correct location.
Another option is to use a {reg:...} constant, assuming that the path you are trying to locate is specified somewhere in the registry (which is usually the case).
If the path is not already specified somewhere well-defined in the Registry when the other app is installed, and you don't have some other means to quickly identify where the other app is located (note that doing a global search of the user's HD is not a valid option), then you should add a page that prompts the user to enter the location themselves (which you can then verify that they have chosen the correct location). You can see examples of prompting the user for information and then doing something with that info in the CodeDlg.iss example included with Inno, and in the ISXKB wiki.

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.

Need a way to get the version # used by the msi installer at run time in c#, without knowing the location of the msi file used to install

I'm developing a scheme to automatically update my program from a central point. To assist me in this I need a way to get the version # of the msi file used to install the progarm at runtime, so I can compare the installed version with the latest version on the server (already solved this part) and decide whether or not to update. To be clear, I already have a way of opening up msi files using msi.dll and getting the version # out. The problem is one of bootstrapping. If the user installs the program for the very first time, how can my program know where to find the msi file (on the client)?
The solution can be as simple as the msi creating a text file with the version # in it when it runs. I'd like to avoid querying the registry if I can.
If I can't figure this out I'm going to have to take special care to keep the version #'s the same in the GUI project and also the MSI installer, and that thought annoys me.
Any thoughts?
I assume you want to get the ProductVersion property of the MSI.
You can do this fairly easily using COM.
Add a COM reference to "Microsoft Windows Installer Object Library" to your C# project.
Then try the following program:
namespace TestCS
{
using System;
using WindowsInstaller;
internal class Test
{
private static void Main(string[] args)
{
if (args.Length < 1)
{
return;
}
Console.WriteLine(GetMsiVersion(args[0]));
}
private static string GetMsiVersion(string installerPath)
{
Type t = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer inst = (Installer)Activator.CreateInstance(t);
Database d = inst.OpenDatabase(
installerPath,
MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);
View v = d.OpenView(
"SELECT * FROM Property WHERE Property = 'ProductVersion'");
v.Execute(null);
Record r = v.Fetch();
string result = r.get_StringData(2);
return result;
}
}
}
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall registry key contains ProductCode subkeys of installed programs. Control Panel's "Add/Remove Problems" and MSI Engine work with this branch.
Iterating through these subkeys you can find the GUID of your program (if you keep old value when changing version in Setup-and-Deployment project). Under that subkey 'DisplayVersion' string value will contain installed version (corresponds to 'Version' property in SnD project).
If you do change ProductCode when increasing Version number (as VisualStudio recommends), 'DisplayName' string may be useful for figuring out which subkey is representing your program, it corresponds to 'ProductName' property in SnD project.
Some programs may be listed in HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall when installed on a per-user basis (e.g. via ClickOnce).
On 64-bit systems there's HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall for 32-bit programs in addition to the original, which in that environment keeps track of 64-bit ones.

VC++: CRegKey.QueryBinaryValue() method not working for Windows 7

I'm developing a tool in VC++ which fetches system information for Windows 7:
Here is the sample code snippet:
CRegKey key;
if(ERROR_SUCCESS == key.Open(hKey, pPath, KEY_READ))
{
// read the value, length will contain the size after the call
if (ERROR_SUCCESS != key.QueryBinaryValue(pValueName, pData, &length))
{
// error occurred
length = 0;
}
key.Close();
}
else
{
length = 0;
}
The length returned is 0.
QueryBinaryValue() method which tries to read REG_BINARY key from registry is not working properly for Windows 7 and thowing error code as 2 (key not found). The same code works well for XP, Vista.
Two things to look into:
Is it possible insufficiante permissions are preventing you from opening the key on 7? IIRC, Process Monitor (suggested by Richard) would show you the reason of the failure, including whether the access was denied.
64 bit versions of Windows contain a sub-system for 32 bit executables. These executables see a different view of the system folder (SysWOW64, instead of System32) and a different view of the registry. If 7 is 64 bit and your app is 32 bit, it is possible you and your app are not looking at the same registry hives - when you run regedit, you're watching the main 64 bit registry. However, a 32 bit executable would be looking at the WOW hives. If this seems to be the case, you can use the regedit that's under SysWOW64. Being a 32 bit executable, it will show you exactly what your app sees.
Have you checked that both the key and value exist in the Windows 7 registry by another route (e.g. RegEdit)?
Process Monitor might show up the underlying problem. Specifically exactly what is failing.
Without knowing the key/value you are trying to access hard to be more specific.

Resources