问题描述
我们正在尝试从Windows服务模拟登录用户。这是使用CreateProcessAsUser()API从服务启动exe。流程启动工作正常。但是当更改语言环境并在重新启动后从服务启动exe时,
exe的UI不会显示为本地化。 UI仍然是英语,这是默认的操作系统安装语言。例如,当操作系统语言更改为法语并且从服务启动的过程时,该过程仍以英语显示。如果我们直接启动
exe,那么启动本地化的exe。我们知道存储当前用户的默认语言和语言存储在注册表中的两个单独位置。我们尝试通过使用_wsetlocale()(_wsetlocale(
LC_ALL," fr-FR)显式设置定位,然后通过这个没有帮助调用CreateProcessAsUser()。无论如何我们可以使用当前记录的语言环境启动exe user?下面是最小错误处理的代码:
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL bResult;
DWORD dwSessionID ;
DWORD dwTokenUIAccess;
DWORD winlogonpid;
HANDLE hUserToken;
HANDLE hUserTokenDup;
HANDLE hPToken;
HANDLE hProcess;
LPVOID pEnviron;
ZeroMemory(& pi,sizeof(pi));
PWTS_SESSION_INFO psession;
DWORD dwCount;
if(!WTSEnumrateSession(WTS_CURRENT_SERVER_HANDLE,0,1,& psession,&) ; dwCount);
{
return;
}
for(DWORD dw = 0; dw< dwCount; ++ dw)
{
WTS_SESSION_INFO SessionInfo = psession [dw];
if(WTS_ACTIVE == SessionInfo.State)
{
dwSessionId = SessionInfo.SessionId;
打破;
}
}
PROCESSENTRY32 procEntry;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
procEntry.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hSnap,& procEntry))
{
}
do
{
if(_wcsicmp(procEntry.szExeFile,L" winlogon.exe")== 0)
{
DWORD winlogonsessionid = 0;
if(ProcessIdToSessionID(procEntry.th32ProcessID,& winlogonsessionid)&& winlogonsessionid == dwSessionId)
{
winlogonpid = procEntr32.th32ProcessID;
休息;
}
}
} while(Prccess32Next(hSnap,& procEntry));
WTSQueryUserToken(dwSessionId,& UserToken);
dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
ZeroMemory(& si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop =(LPWSTR)L" winsta0\default" ;;
TOKEN_PRIVILEGES tp;
LUID luid;
hProcess = OpenProcess(MAXIMUM_ALLOWED,FALSE,winlogonpid);
if(!:: OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE,& hPToken))
{
return;
}
if(!LookUpPrivilegeValue(NULL,SE_DEBUG_NAME,& luid))
{
return;
}
tp.PrivilegeCount = 1;
tp.Privileges [0] .Luid = luid;
tp.Privileges [0] .Attributes = SE_PRIVILGE_ENABLED;
if(!DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,& hUserTokenDup))
{
return;
}
if(SetTokenInformation(hUserTokenDup,TokenSessionID,(LPVOID)& dwSessionID,sizeof(DWORD)))
{
return;
}
if(SetTokenInformation(hUserTokenDup,TokenUIAccess,(LPVOID)& dwTokenUIAccess,sizeof(DWORD)))
{
return;
}
if(!AdjustTokenPrivileges(hUserTokenDup,FALSE,& tp,sizeof(TOKEN_PRIVILGES),(PTOKEN_PRIVILEGES)NULL,NULL))
{
return;
}
if(GetLastError()== ERRRO_NOT_ALL_ASSIGNED)
{
return;
}
bResult = CreateProcessAsUser(hUserTokenDup,strProcessName,
NULL,
NULL,
NULL,
FALSE,
dwCreationFlags,pEnviron,NULL ,& si,& pi);
We are trying to impersonate the logged in user from a Windows service. This is to launch an exe from the service using CreateProcessAsUser() API. The process launch is working fine. But when locale is changed and the exe is launched from service after restart, the UI of the exe does not appear localized. The UI is still in English which was the default OS install language. For example, when the OS language is changed to French and the process launched from service the process still appears in English. If we launch the exe directly, then the localised exe is launched. We understand that the default language and language of the current user are stored are stored in two separate locations in registry. We tried by explicitly setting locate using _wsetlocale() (_wsetlocale( LC_ALL, "fr-FR) before calling CreateProcessAsUser() by this didnt help. Is there anyway we can launch the exe with the locale of the currently logged user? Below is the code with minimal error handling:
PROCESS_INFORMATION pi; STARTUPINFO si; BOOL bResult; DWORD dwSessionID; DWORD dwTokenUIAccess; DWORD winlogonpid; HANDLE hUserToken; HANDLE hUserTokenDup; HANDLE hPToken; HANDLE hProcess; LPVOID pEnviron; ZeroMemory(&pi, sizeof(pi)); PWTS_SESSION_INFO psession; DWORD dwCount; if (!WTSEnumrateSession(WTS_CURRENT_SERVER_HANDLE, 0, 1, &psession, &dwCount); { return; } for (DWORD dw = 0; dw < dwCount; ++dw) { WTS_SESSION_INFO SessionInfo = psession[dw]; if (WTS_ACTIVE == SessionInfo.State) { dwSessionId = SessionInfo.SessionId; break; } } PROCESSENTRY32 procEntry; HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); procEntry.dwSize = sizeof(PROCESSENTRY32); if (!Process32First(hSnap, &procEntry)) { } do { if (_wcsicmp(procEntry.szExeFile, L"winlogon.exe") == 0) { DWORD winlogonsessionid = 0; if (ProcessIdToSessionID(procEntry.th32ProcessID, &winlogonsessionid) && winlogonsessionid == dwSessionId) { winlogonpid = procEntr32.th32ProcessID; break; } } }while (Prccess32Next(hSnap, &procEntry)); WTSQueryUserToken(dwSessionId, &UserToken); dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.lpDesktop = (LPWSTR)L"winsta0\default"; TOKEN_PRIVILEGES tp; LUID luid; hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, winlogonpid); if (!::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, &hPToken)) { return; } if (!LookUpPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { return; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILGE_ENABLED; if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hUserTokenDup)) { return; } if (SetTokenInformation(hUserTokenDup, TokenSessionID, (LPVOID)&dwSessionID, sizeof(DWORD))) { return; } if (SetTokenInformation(hUserTokenDup, TokenUIAccess, (LPVOID)&dwTokenUIAccess, sizeof(DWORD))) { return; } if (!AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILGES), (PTOKEN_PRIVILEGES)NULL, NULL)) { return; } if (GetLastError() == ERRRO_NOT_ALL_ASSIGNED) { return; } bResult = CreateProcessAsUser(hUserTokenDup, strProcessName, NULL, NULL, NULL, FALSE, dwCreationFlags, pEnviron, NULL, &si, &pi);
这篇关于设置用户区域设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!