C++ C++;搜索Windows注册表
我试图在注册表中搜索特定组(本地->Windows->卸载)中的键,以便最终以编程方式卸载这些应用程序。我在获取密钥名称以便打开它时遇到问题。以下是我尝试过的:C++ C++;搜索Windows注册表,c++,windows,registry,key,C++,Windows,Registry,Key,我试图在注册表中搜索特定组(本地->Windows->卸载)中的键,以便最终以编程方式卸载这些应用程序。我在获取密钥名称以便打开它时遇到问题。以下是我尝试过的: void Uninstall::uninstallProgram(string appName) { HKEY currentKey; TCHAR name[1024]; DWORD dwSize = 1024, dwIdx = 0; FILETIME fTime; long result;
void Uninstall::uninstallProgram(string appName)
{
HKEY currentKey;
TCHAR name[1024];
DWORD dwSize = 1024, dwIdx = 0;
FILETIME fTime;
long result;
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, POLICY_KEY, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, ¤tKey);
if (result != ERROR_SUCCESS)
{
cout << "Error opening Installation Registry, verify that this location exists under: " << POLICY_KEY << endl;
cin.get();
}
else
{
/*
* The installation path has been verified, now need to start looking for the correct program to uninstall
*/
for(int index = 0; result == ERROR_SUCCESS; index++)
{
if (RegEnumKeyEx(currentKey, 0, name, &dwSize, NULL, NULL, NULL, &fTime))
{
cout << string() << name << endl;
// if (name == appName)
// {
// system(execute the uninstall string)
// }
}
}
}
void Uninstall::Uninstall程序(字符串appName)
{
HKEY currentKey;
TCHAR名称[1024];
DWORD dwSize=1024,dwIdx=0;
文件时间fTime;
长期结果;
结果=RegOpenKeyEx(HKEY_本地_机器、策略_键、0、键查询_值、键设置_值和当前键);
如果(结果!=错误\u成功)
{
cout用于注册表访问的原始api非常难看-它的标准做法是使用许多可用的包装器类中的一个,从而使整个过程不那么痛苦。codeproject上有几十个这样的类。您必须使用当前索引来获取名称,然后检查错误\u无更多\u项
:
bool quit = false;
for(int index = 0; !quit; index++)
{
LSTATUS Return = RegEnumKeyEx(currentKey, index, name, &dwSize, NULL, NULL, NULL, &fTime);
if(Return == ERROR_NO_MORE_ITEMS)
{
quit = true;
}
else if(Return == ERROR_SUCCESS)
{
cout << string() << name << endl;
}
else
{
quit = true;
}
}
bool quit=false;
对于(int index=0;!quit;index++)
{
LSTATUS Return=RegEnumKeyEx(currentKey、index、name和dwSize、NULL、NULL、NULL和fTime);
如果(返回==错误\u无\u更多\u项)
{
退出=真;
}
else if(返回==错误\成功)
{
cout您需要在RegEnumKeyEx调用中包含索引变量。您总是为dwIndex参数传递0。当它返回错误项时停止枚举。您似乎只是忘记了请求KEY\u ENUMERATE\u SUB\u KEY访问权限。另外,我可能不清楚您到底想做什么,但AFAIK卸载文件夹具有不同的位置
HKEY currentKey;
TCHAR name[1024];
DWORD dwSize = 1024, dwIdx = 0;
long result;
result = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall" ), 0, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_SET_VALUE, ¤tKey);
if (result != ERROR_SUCCESS)
{
// fail
}
else
{
DWORD index = 0;
while ( ERROR_SUCCESS == RegEnumKeyEx(currentKey, index, name, &dwSize, NULL, NULL, NULL, NULL) ) {
// name buffer is already contains key name here
// ...
dwSize = 1024; // restore dwSize after is is set to key's length by RegEnumKeyEx
++index; // increment subkey index
}
}
下面是一个可以在注册表中递归搜索值名的工作编译代码,我知道洛塔人正在寻找它,我认为目前还没有可以执行此操作的工作代码
使用MinGW编译
// Say Shaloom to Ammar Hourani who did code troubleshooting and compiled this
// QueryKey - Enumerates the subkeys of key and its associated values.
// hKey - Key whose subkeys and values are to be enumerated.
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <iostream.h>
#include <wchar.h>
#include <string.h>
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
void QueryKey(char * originalpath , char * searchvalue)
{
HKEY hKey;
if( RegOpenKeyEx( HKEY_CURRENT_USER,TEXT(originalpath),0,KEY_READ,&hKey) == ERROR_SUCCESS)
{
TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name
DWORD cbName; // size of name string
TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name
DWORD cchClassName = MAX_PATH; // size of class string
DWORD cSubKeys=0; // number of subkeys
DWORD cbMaxSubKey; // longest subkey size
DWORD cchMaxClass; // longest class string
DWORD cValues; // number of values for key
DWORD cchMaxValue; // longest value name
DWORD cbMaxValueData; // longest value data
DWORD cbSecurityDescriptor; // size of security descriptor
FILETIME ftLastWriteTime; // last write time
DWORD i, retCode;
CHAR achValue[MAX_VALUE_NAME];
DWORD cchValue = MAX_VALUE_NAME;
char * dndr = new char[MAX_VALUE_NAME]();
// Get the class name and the value count.
retCode = RegQueryInfoKey(
hKey, // key handle
achClass, // buffer for class name
&cchClassName, // size of class string
NULL, // reserved
&cSubKeys, // number of subkeys
&cbMaxSubKey, // longest subkey size
&cchMaxClass, // longest class string
&cValues, // number of values for this key
&cchMaxValue, // longest value name
&cbMaxValueData, // longest value data
&cbSecurityDescriptor, // security descriptor
&ftLastWriteTime); // last write time
// Enumerate the subkeys, until RegEnumKeyEx fails.
if (cSubKeys)
{
for (i=0; i<cSubKeys; i++)
{
cbName = MAX_KEY_LENGTH;
retCode = RegEnumKeyEx(hKey, i,achKey,&cbName,NULL,NULL,NULL,&ftLastWriteTime);
if (retCode == ERROR_SUCCESS)
{
strcpy(dndr,originalpath);
strcat(dndr,"\\");
strcat(dndr,achKey);
QueryKey(dndr,searchvalue);
}
}
}
// Enumerate the key values.
if (cValues)
{
for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++)
{
cchValue = MAX_VALUE_NAME;
//achValue[0] = '\0';
memset(achValue, 0, sizeof(achValue));
retCode = RegEnumValue(hKey, i,
achValue,
&cchValue,
NULL,
NULL,
NULL,
NULL);
if (retCode == ERROR_SUCCESS )
{
if (!strncmp(achValue,searchvalue,strlen(searchvalue))) cout << "\n One Hit at: " << originalpath << endl;
}
}
}
}
RegCloseKey(hKey);
}
int __cdecl _tmain(void)
{
QueryKey("Software\\Microsoft\\Office","MTTA");
cin.get();
return 1;
}
//向Ammar Hourani说Shaloom,Ammar Hourani做了代码故障排除并编译了这个
//QueryKey-枚举键及其关联值的子键。
//hKey-要枚举其子键和值的键。
#包括
#包括
#包括
#包括
#包括
#包括
#定义最大键长255
#定义最大值\名称16383
void QueryKey(char*originalpath,char*searchvalue)
{
HKEY HKEY;
if(RegOpenKeyEx(HKEY\U当前用户、文本(原始路径)、0、KEY\U READ和HKEY)=错误\U成功)
{
TCHAR achKey[MAX_KEY_LENGTH];//子键名称的缓冲区
DWORD cbName;//名称字符串的大小
TCHAR achClass[MAX_PATH]=TEXT(“”;//类名的缓冲区
DWORD cchClassName=MAX_PATH;//类字符串的大小
DWORD cSubKeys=0;//子键数
DWORD cbMaxSubKey;//最长子键大小
DWORD cchMaxClass;//最长的类字符串
DWORD cValues;//键的值数
DWORD cchMaxValue;//最长值名称
DWORD cbMaxValueData;//最长值数据
DWORD cbSecurityDescriptor;//安全描述符的大小
FILETIME ftLastWriteTime;//上次写入时间
dwordi,retCode;
CHAR achValue[最大值\名称];
DWORD cchValue=最大值\名称;
char*dndr=新字符[MAX_VALUE_NAME]();
//获取类名和值计数。
retCode=RegQueryInfoKey(
hKey,//键句柄
achClass,//类名称的缓冲区
&cchClassName,//类字符串的大小
NULL,//保留
&cSubKeys,//子键数
&cbMaxSubKey,//最长子键大小
&cchMaxClass,//最长的类字符串
&cValues,//此键的值数
&cchMaxValue,//最长值名称
&cbMaxValueData,//最长值数据
&cbSecurityDescriptor,//安全描述符
&ftLastWriteTime);//上次写入时间
//枚举子键,直到RegEnumKeyEx失败。
if(csubkey)
{
对于(i=0;当我这样运行它时,我的“Return”值总是返回为5,这是拒绝访问的,即使我是以管理员的身份运行eclipse。我故意使用原始api来实现它,以便了解它是如何工作的,最坏的情况下,我将返回到这些包装器中的一个。不客气。研究这一点很有趣:)我以前从未使用过注册表。顺便说一句,有一个删除注册表项的例子,在我的注册表中搜索显示,为了找到要卸载的所有条目,您应该检查几个位置:HKEY\U CURRENT\U USER\Software\Microsoft\Windows\CurrentVersion\uninstall HKEY\U LOCAL\U MACHINE\Software\Microsoft\Windows\CurrentVersion\uninstall HKEY\U LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall这是谷歌的要求,但似乎第一个是针对仅为当前用户安装的应用程序,第二个是针对所有用户的应用程序,第三个是针对32-64兼容性(我有64位Windows 7)。此外,我认为进入HKEY_LOCAL_机器(至少是取下钥匙)需要高度。