如何在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);
}
如何在Windows服务程序中读写HKEY_CURRENT_USER注册表的更多相关文章
- 如何在Windows服务程序中添加U盘插拔的消息
研究了下这个问题,主要要在一般的windows服务程序中修改两个地方: 一.调用RegisterServiceCtrlHandlerEx VOID WINAPI SvcMain( DWORD dwAr ...
- 如何在C#中读写INI文件
INI文件就是扩展名为"ini"的文件.在Windows系统中,INI文件是很多,最重要的就是"System.ini"."System32.ini&q ...
- 如何在 Windows 10 中搭建 Node.js 环境?
[编者按]本文作者为 Szabolcs Kurdi,主要通过生动的实例介绍如何在 Windows 10 中搭建 Node.js 环境.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 在本文中 ...
- 64 位 Windows 平台开发注意要点之注册表重定向
Window 系统错误代码 ERROR_SUCCESS,本博客中一律使用 NO_ERROR 代替.虽然 ERROR_SUCCESS 与 NO_ERROR 是完全等价的,都代表成功,但是后者却和其他错误 ...
- QSettings配置读写-win注册表操作-ini文件读写
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSettings配置读写-win注册表操作-ini文件读写 本文地址:http:// ...
- 使用Windows命令行reg控制注册表键值
使用Windows命令行reg控制注册表键值 引言 熟悉Windows操作系统的朋友可能都知道,Windows操作系统下的注册表相当于系统的数据库 ,部分软件将自己的配置信息都放在注册表里面,而注册表 ...
- SQL Server 2008 安装过程中遇到“性能计数器注册表配置单元一致性”检查失败 问题的解决方法
操作步骤: 1. 在 Microsoft Windows 2003 或 Windows XP 桌面上,依次单击"开始"."运行",然后在"打开&quo ...
- 关于软件开发中兼容win7注册表的解决方案
关于软件开发中兼容win7注册表的解决方案 编写人:CC阿爸 2014-3-14 l 近来在开发一winform程序时,发现在xp 系统访问注册表一切正常.可偏这个时候,微软又提醒大家.Xp今年 ...
- 64位Windows操作系统中的注冊表
x64系统上有x64.x86两种注冊表,记录下. 64 位Windows系统中的注冊表分为 32 位注冊表项和 64 位注冊表项.很多 32 位注冊表项与其对应的 64 位注冊表项同名. 在64位版本 ...
随机推荐
- Unity3D之MeleeWeaponTrail武器轨迹插件的使用
MeleeWeaponTrail是Unity Asset Store中的一个免费插件.主要是用于显示武器的轨迹. 首先,找到武器绑定的骨骼.并在骨骼以下加入轨迹显示的起点和终点. 接着,给该骨骼加入M ...
- lamp安装指南(转)
主要软件包, 1. httpd-2.2.6.tar.gz 2. mysql-5.0.45-linux-i686-glibc23.tar.gz ( 这个版本是已编译好的压缩包,解压后稍做配置即可使用 ) ...
- linux系统中中断已连接的用户
1.用w命令查看当前系统登录的用户 [root@rhel7 ~]# w :: up :, users, load average: 0.00, 0.01, 0.05 USER TTY FROM LOG ...
- tail和head命令
[root@rhel7 ~]# cat rusky --cat命令查看文件内容 line1 line2 line3 line4 line5 line6 line7 line8 line9 line10 ...
- CentOS 7 修改hostname
centOS 7 里面修改hostname的方式有所改变,修改/etc/hosts和/etc/sysconfig/network两个文件已经不能生效.使用的新命令是 : hostnamectl set ...
- 画画 保存为图片 MaskFilter 边缘效果
使用 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> publ ...
- javascript小数四舍五入
javascript小数四舍五入 1. function get(){ var s = 22.127456 + ""; var str = s.substring(0, ...
- CSS元素分类及区别
元素是文档结构的基础,在CSS中,每个元素生成了一个包含了元素内容的框(box,也译为“盒子”).但是不同的元素显示的方式会有所不同,例如<div>和<span>就不同,而&l ...
- ViewState探索
什么是 view state? View State是客户端状态管理重要机制之一.当页面PostBack(向服务器发送或获得数据)时,它能存储页面的值.ASP.NET把View State属性作为页面 ...
- Windows Server 2003 SP2 R2 企业版/标准版/32与64位 CD-KEY
微软发布Windows Server 2003 R2版的目的是希望透过它填补Windows Server 2003 SP1和Longhorn Server之间的产品发布时间间隔.所以Windows S ...