ImanalogateLoggedOnUser 成功,但辅助进程仍在初始上下文中运行
ImpersonateLoggedOnUser is successful but secondary process is still run in the initial context
我有一个安装程序,在安装完成后尝试在当前用户上下文中(重新)启动我的应用程序。安装程序在 SYSTEM 上下文中运行,在启动应用程序之前,它会尝试(理论上成功)模拟当前用户。但是,当我查看任务管理器时,我看到我的应用程序正在系统上下文中运行。
这是(来自)我的代码的片段:
TCHAR szUsername[128] = _T("");
DWORD dwUsernameSize = 128;
GetUserName(szUsername, &dwUsernameSize);
// Lets the calling process impersonate the security context of a logged-on user.
if (!ImpersonateLoggedOnUser(hToken))
{
throw Win32Exception(GetLastError(), _T("Failed to impersonate current user"));
}
TCHAR szUsername2[128] = _T("");
DWORD dwUsernameSize2 = 128;
GetUserName(szUsername2, &dwUsernameSize2);
MLOGD(_T("ProcessUtils::StartProcessInCurrentUserContext: Successfully impersonated %s"), szUsername2);
ProcessUtils::StartProcess(sExeName, lstParams, sWorkingDir, bWaitToFinish, errCode);
ProcessUtils::StartProcess是CreateProcess的包装器。
szUsername 包含 SYSTEM,szUsername2 包含当前用户。因此,ImanalogateLoggedOnUser 是成功的。但是,如上所述,该过程是在 SYSTEM 上下文中启动的,而不是在当前用户上下文中启动的。
我不确定这会有多大帮助,但我的安装程序是用 NSIS 编写的,它通过用 C/C++ 编写的插件从上面调用包含代码的函数。
有谁知道为什么我的应用程序不在当前用户上下文中启动?
Win32 CreateProcess 在与调用方相同的安全上下文中创建一个进程,该调用方是 SYSTEM(即使您正在模拟)。
认为您需要调用 CreateProcessAsUser。
我也遇到了一个非常相似的问题正在处理安装程序应用程序。在很多挫折之后,导致通过尝试在当前上下文中启动应用程序失败用户使用CreateProcessAsUser
,我终于放弃了。彻底之后在网络上搜索,我找到了一个使用 IShellDispatch2
界面。下面是一个示例:
#include <Windows.h>
#include <exdisp.h>
#include <Shobjidl.h>
#include <Shlwapi.h>
#include <comutil.h>
#include <SHLGUID.h>
#include <cstdlib>
#include <iostream>
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "comsuppw.lib")
bool ShellExecuteAsCurrentUser(const TCHAR *pcOperation, const TCHAR *pcFileName, const TCHAR *pcParameters,
const TCHAR *pcsDirectory, const DWORD dwShow)
{
bool bSuccess = false;
IShellWindows *psw = NULL;
HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw));
if(SUCCEEDED(hr))
{
HWND hwnd = 0;
IDispatch* pdisp = NULL;
_variant_t vEmpty;
if(S_OK == psw->FindWindowSW(&vEmpty, &vEmpty, SWC_DESKTOP, reinterpret_cast<long*>(&hwnd), SWFO_NEEDDISPATCH, &pdisp))
{
if((hwnd != NULL) && (hwnd != INVALID_HANDLE_VALUE))
{
IShellBrowser *psb;
hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb));
if(SUCCEEDED(hr))
{
IShellView *psv = NULL;
hr = psb->QueryActiveShellView(&psv);
if(SUCCEEDED(hr))
{
IDispatch *pdispBackground = NULL;
HRESULT hr = psv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&pdispBackground));
if(SUCCEEDED(hr))
{
IShellFolderViewDual *psfvd = NULL;
hr = pdispBackground->QueryInterface(IID_PPV_ARGS(&psfvd));
if(SUCCEEDED(hr))
{
IDispatch *pdisp = NULL;
hr = psfvd->get_Application(&pdisp);
if(SUCCEEDED(hr))
{
IShellDispatch2 *psd;
hr = pdisp->QueryInterface(IID_PPV_ARGS(&psd));
if(SUCCEEDED(hr))
{
_variant_t verb(pcOperation);
_variant_t file(pcFileName);
_variant_t para(pcParameters);
_variant_t dir(pcsDirectory);
_variant_t show(dwShow);
if(SUCCEEDED(psd->ShellExecute(file.bstrVal, para, vEmpty, verb, show)))
bSuccess = true;
psd->Release();
psd = NULL;
}
pdisp->Release();
pdisp = NULL;
}
}
pdispBackground->Release();
pdispBackground = NULL;
}
psv->Release();
psv = NULL;
}
psb->Release();
psb = NULL;
}
}
pdisp->Release();
pdisp = NULL;
}
psw->Release();
psw = NULL;
}
return bSuccess;
}
int main(int argc, char *argv[])
{
CoInitialize(NULL);
if(ShellExecuteAsCurrentUser(L"open", L"notepad", nullptr, nullptr, SW_SHOWNORMAL))
std::cout << "SUCCESS" << std::endl;
CoUninitialize();
return 0;
}
这只是一个快速演示,ShellExecuteAsCurrentUser
的实现可以是通过对 COM 接口使用智能指针和一些重构进行了改进。此方法在WinXP SP3 - Win 8.1版本上为我工作,不确定它是否适用于Windows 10。为更多详细信息,请查看作者 GitHub 页面:
https://github.com/lordmulder/stdutils/tree/master/Contrib/StdUtils
如果您阅读了 CreateProcess 的文档,您会在前三句话中找到问题的答案:
创建新进程及其主线程。新进程在调用进程的安全上下文中运行。
如果调用进程正在模拟其他用户,则新进程将使用调用进程的令牌,而不是模拟令牌。
真的没什么好说的;你描述的行为是有记录的。 如果要以其他用户身份创建进程,则必须使用 CreateProcessAsUser 或相关函数之一。
- 运行同一解决方案的另一个项目的项目
- CMake-按正确顺序将项目与C运行时对象文件链接
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 代码在main()中运行,但在函数中出现错误
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- #为""定义宏;静态";针对不同的上下文
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 与互斥锁相比,旋转锁可以保证上下文切换
- 实现上下文切换 - 第二个函数不再运行
- 在运行时从OpenGL上下文切换到D3D/DX上下文(或其他上下文)
- 如何检查当前的 OpenGL 上下文是否在 Geforce 卡上运行
- 单击上下文菜单项时运行程序
- 设计建议:llvm多个运行时上下文
- 在另一个进程上下文下运行命令
- Google V8引擎可以在不同的上下文、不同的线程中同时运行不同的javascript吗?
- 未能设置运行测试的执行上下文
- 激活上下文生成失败.VC运行时错误
- Android opengl在两个线程上运行的两个上下文之间共享纹理
- 如何在QGraphicsItem中从上下文菜单运行函数