
正文
如何在Windows服务程序中读写HKEY_CURRENT_USER注册表
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
在服务程序中想要对注册表HKEY_CURRENT_USER下的内容进行读写,不会返回失败,但是始终无效。原因是:
1.服务运行在系统权限之下,而不是任何一个用户
2.HKEY_CURRENT_USER存储的是当前用户的信息================>导致在服务中读取HKEY_CURRENT_USER实际操作的不是当前登录的用户的数据。
所以如果我要操作HKEY_CURRENT_USER之内的键值,就必须模拟当前用户去读取。
有几种思路可以做到:
1.创建一个用户进程去操作注册表,使用CreateProcessAsUser函数可以做到
2.让当前线程模拟当前登录用户的安全上下文(lets the calling thread impersonate the security context of a logged-on user)。使用ImpersonateLoggedOnUser 函数可以做到。
第一个方法需要用到另外一个程序,感觉比较麻烦。
以下演示第二种方法:
BOOL GetTokenByName(HANDLE &hToken,LPTSTR lpName)
{
if (!lpName)
return FALSE; HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pe32 = {}; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, );
if (hProcessSnap == INVALID_HANDLE_VALUE)
return (FALSE); pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hProcessSnap, &pe32))
{
do
{
if(!_tcscmp(_tcsupr(pe32.szExeFile),_tcsupr(lpName)))
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pe32.th32ProcessID);
bRet = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);
CloseHandle (hProcess);
CloseHandle (hProcessSnap);
return (bRet);
}
}
while (Process32Next(hProcessSnap, &pe32));
bRet = FALSE;
}
else
{
bRet = FALSE;
} CloseHandle (hProcessSnap);
return (bRet);
}
//
//获取用户sid
//
bool GetAccountSid(LPTSTR AccountName, PSID *Sid)
{
PSID pSID = NULL;
DWORD cbSid = ;
LPTSTR DomainName = NULL;
DWORD cbDomainName = ;
SID_NAME_USE SIDNameUse;
BOOL bDone = FALSE;
try
{
if(!LookupAccountName(NULL,
AccountName,
pSID,
&cbSid,
DomainName,
&cbDomainName,
&SIDNameUse))
{
pSID = (PSID)malloc(cbSid);
DomainName = (LPTSTR)malloc(cbDomainName * sizeof(TCHAR));
if(!pSID || !DomainName)
{
throw;
}
if(!LookupAccountName(NULL,
AccountName,
pSID,
&cbSid,
DomainName,
&cbDomainName,
&SIDNameUse))
{
throw;
}
bDone = TRUE;
}
}
catch(...)
{
//nothing
}
if(DomainName)
{
free(DomainName);
} if(!bDone && pSID)
{
free(pSID);
}
if(bDone)
{
*Sid = pSID;
}
return bDone;
}// 模拟当前用户环境设置默认打印机
void SimulateCurrentUserSetDefaultPrinter()
{
HANDLE hToken = NULL;
do
{
if (!GetTokenByName(hToken,_T("EXPLORER.EXE")))
{
break;
} // 模拟登录用户的安全上下文
if(FALSE == ImpersonateLoggedOnUser(hToken))
{
break;
} // 获取用户名
TCHAR szUsername[MAX_PATH];
DWORD dwUsernameLen = MAX_PATH;
if(FALSE == GetUserName(szUsername, &dwUsernameLen))
break; // 到这里已经模拟完了,别忘记返回原来的安全上下文
if(FALSE == RevertToSelf())
break; // 获取sid
PSID pSid = NULL;
LPWSTR sid;
GetAccountSid(szUsername, &pSid); //获取得到的是一个结构体
ConvertSidToStringSid(pSid, &sid); //从结构体中得到sid串 // 设置默认打印机信息
//SetDefaultPrinter(PSSD_PRINTER_NAME);
HKEY hKey;
int i=; //操作结果:0==succeed
wchar_t lswRegValue[MAX_PATH];
StringCchPrintf(lswRegValue, MAX_PATH, L"%s,winspool,%s", PSSD_PRINTER_NAME, PSSD_PRINTER_PORT_NAME);
wchar_t lswKeyPath[MAX_PATH] = {};
StringCchPrintf(lswKeyPath, MAX_PATH, L"%s\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows", sid);
if(RegOpenKeyEx(HKEY_USERS, lswKeyPath, , KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
if(RegSetValueEx(hKey,L"Device",NULL,REG_SZ, (const LPBYTE)lswRegValue, (wcslen(lswRegValue) + ) * sizeof(wchar_t))!=ERROR_SUCCESS)
{
i=;
}
RegCloseKey(hKey);
}
else
{
i=;
}
if( == i)
{
OutputDebugStringW(L"STST: 设置默认打印机失败");
}
else
{
SendNotifyMessage(HWND_BROADCAST, WM_SETTINGCHANGE, , );
} } while (false);
if(NULL != hToken)
CloseHandle(hToken);
}





