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.
Related
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)
I've been struggling to get my application deployed properly for several weeks now (it's a hobby), and I just don't know what else to try.
I started a new project in Qt Creator (2.6.1), by selecting Applications -> Qt Quick 2 Application (Built-in Elements). I tweaked the QML to make the background blue and text red:
main.qml
import QtQuick 2.0
Rectangle {
width: 360
height: 360
color: "blue" // Added!
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
color: "red" // Added!
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
I'm using Qt 5.0.1 and the x86 MSVC 2010 compiler. I built the Release version and it ran fine in QtCreator. If you need more compiler specifics, I'll post them.
To deploy, I created a new folder on my desktop called HelloWorld/ and copied everything from H:\Qt\Qt5.0.1\5.0.1\msvc2010\bin\* and H:\Qt\Qt5.0.1\5.0.1\msvc2010\plugins\* and 'H:\Qt\Qt5.0.1\5.0.1\msvc2010\qml* into it, along with the Release HelloWorld.exe executable.
Overkill? Yes. But I'm desperate.
When I run HelloWorld/HelloWorld.exe in Windows 7 64-bit, the application runs fine. But when I copy this HelloWorld/ folder over into a virtual machine running Windows XP 32-bit, it shows a properly-sized window, but with nothing in it (white, with no text). When clicking in the center of the window, the window closes as it should.
So I loaded the executable in Dependency Walker, but nothing looked out of the ordinary (IESHIMS.DLL and WER.DLL were of course missing). I ran Start Profile, and got a slew of red errors:
GetProcAddress(0x7C800000 [KERNEL32.DLL], "FlsAlloc") called from "MSVCR100.DLL" at address 0x78ABBA3B and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x7C800000 [KERNEL32.DLL], "FlsGetValue") called from "MSVCR100.DLL" at address 0x78ABBA48 and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x7C800000 [KERNEL32.DLL], "FlsSetValue") called from "MSVCR100.DLL" at address 0x78ABBA55 and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x7C800000 [KERNEL32.DLL], "FlsFree") called from "MSVCR100.DLL" at address 0x78ABBA62 and returned NULL. Error: The specified procedure could not be found (127).
LoadLibraryExW("C:\documents and settings\owner\desktop\helloworld\platforms\qminimald.pdb", 0x00000000, DONT_RESOLVE_DLL_REFERENCES) returned NULL. Error: %1 is not a valid Win32 application (193).
LoadLibraryExW("C:\documents and settings\owner\desktop\helloworld\platforms\qwindowsd.pdb", 0x00000000, DONT_RESOLVE_DLL_REFERENCES) returned NULL. Error: %1 is not a valid Win32 application (193).
GetProcAddress(0x7E410000 [USER32.DLL], "UpdateLayeredWindowIndirect") called from "QWINDOWS.DLL" at address 0x013A8749 and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x7C9C0000 [SHELL32.DLL], "SHCreateItemFromParsingName") called from "QWINDOWS.DLL" at address 0x013A8997 and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x7C9C0000 [SHELL32.DLL], "SHGetStockIconInfo") called from "QWINDOWS.DLL" at address 0x013A89C9 and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x7C800000 [KERNEL32.DLL], "GetTickCount64") called from "QT5CORE.DLL" at address 0x670726A7 and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x755C0000 [MSCTFIME.IME], "ImeGetImeMenuItems") called from "IMM32.DLL" at address 0x76397354 and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x4FDD0000 [D3D9.DLL], "Direct3DCreate9Ex") called from "LIBEGL.DLL" at address 0x01487198 and returned NULL. Error: The specified procedure could not be found (127).
I also tried to run a debug version, but I only have the 64-bit versions of the MSVC100 dll's, so I can't copy them to the XP machine (I can only run the 32-bit redistributable). I don't know what other tools I can use to try to solve my problem.
I know I must be doing something stupid, but I really can't find anything on the internet to help. It's really frustrating to spend so much time developing a Qt application, and then get stuck trying to deploy it.
I should note that the program runs just fine in a Windows 7 32-bit virtual machine (after MSVC2012 redistributable has been installed).
The application I'm really interested in running, runs really strangely in Windows XP. When I first run it, the window sizes properly and a couple text strings show up. But none of the Rectangle{} elements are displayed. I left the app running for a few minutes as I made myself some coffee, and when I returned to my computer, the window was blinking random shapes and text, to the beat of the text cursor! What the heck is that?! It looked like a basic math function was screwed up, so parts of the interface were being displayed at improper sizes and positions. I even saw the real interface show up for one blink of the mouse cursor (and yes, the random shapes appear and disappear to the beat of the mouse cursor).
On a whim, I tried using the application (clicking where I know a text box exists), to populate one of the lists, and it worked! The application is running completely fine, except for the graphics. I know Qt 5.0 reworked some of the OpenGL handling, right? Could this be a bug, or maybe a library I haven't installed?
I also encountered the same problem when deploying quick 2.0 application on Windows XP builded by Qt 5.1 rc1 with ANGLE; It's seems to be ANGLE problem, on http://qt-project.org/wiki/Qt-5-on-Windows-ANGLE-and-OpenGL is recommended to use OPENGL for XP, also Qt 5.1 with OPENGL works for me on Windows XP
Install Microsoft Visual C++ 2010 Redistributable Package (x86)
on client machine (windows xp).
Use release build, not debug build, You seems to be using Debug
version.
Don't use OpenGL(Most of XP Users may note have updated OpenGL
version, otherwise you may have to force them to upgrade it.)
Update
Use OpenGL for Windows XP. User have to install or upgrade their OpenGL drivers. Read this.
Try using the MinGW version instead of the VC++ one. It's likely that there are layers and layers of .Net stuff preventing you from running on XP. XP came out before 90% of the current .Net stuff existed which is why it wont work as it's not installed.
Just a guess but its worth a shot.
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\\
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.
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.