C# 获取Csrss.exe的路径

C# 获取Csrss.exe的路径,c#,c++,.net,winapi,C#,C++,.net,Winapi,我想获取指向Csrss.exe的PID的路径。我不能使用OpenProcess函数,因为MSDN特别声明它将返回对Csrss.exe和Idle等进程的访问被拒绝。我试过使用 Process32Next 得到 PROCESSENTRY32 结构,它有一个exeName字段。但是,这只是可执行文件的名称。您可以通过调用获取完整路径 QueryFullProcessImageName 但是,该函数接受一个HPROCESS,不幸的是,它需要调用OpenProcess。 我之所以需要这样做,是因为我

我想获取指向Csrss.exe的PID的路径。我不能使用OpenProcess函数,因为MSDN特别声明它将返回对Csrss.exe和Idle等进程的访问被拒绝。我试过使用

Process32Next
得到

PROCESSENTRY32
结构,它有一个exeName字段。但是,这只是可执行文件的名称。您可以通过调用获取完整路径

QueryFullProcessImageName
但是,该函数接受一个HPROCESS,不幸的是,它需要调用
OpenProcess

我之所以需要这样做,是因为我正在尝试验证某个进程是否是Microsoft签名的进程,因此我获取了进程的PID,为了检查它是否已签名,我必须获取该进程的路径。

事实证明,Vista及更高版本中有一个用于获取进程路径和新进程访问()的新函数:

您可以使用此权限获取进程的句柄。以下是示例:

#include <Windows.h>
#include <psapi.h>
#include <iostream>
#include <tlhelp32.h>

BOOL SetPrivilege(
    HANDLE hToken,  // token handle 
    LPCTSTR Privilege,  // Privilege to enable/disable 
    BOOL bEnablePrivilege  // TRUE to enable. FALSE to disable 
)
{
    TOKEN_PRIVILEGES tp = { 0 };
    // Initialize everything to zero 
    LUID luid;
    DWORD cb = sizeof(TOKEN_PRIVILEGES);
    if (!LookupPrivilegeValue(NULL, Privilege, &luid))
        return FALSE;
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if (bEnablePrivilege) {
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    }
    else {
        tp.Privileges[0].Attributes = 0;
    }
    AdjustTokenPrivileges(hToken, FALSE, &tp, cb, NULL, NULL);
    if (GetLastError() != ERROR_SUCCESS)
    {
        std::cout << GetLastError() << std::endl;
        return FALSE;
    }

    return TRUE;
}
int main()
{
    HANDLE curHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
    OpenProcessToken(curHandle, TOKEN_ADJUST_PRIVILEGES, &curHandle);
    BOOL b = SetPrivilege(curHandle, SE_DEBUG_NAME, TRUE);
    wchar_t buf[MAX_PATH] = L"";
    int pid = 668;
    HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
    if (handle)
    {
        GetModuleFileNameExW(handle, 0, buf, MAX_PATH);
        std::wcout << buf << "\n";
    }
    else
    {
        std::cout << "error = " << GetLastError() << std::endl;
    }
    char s[MAX_PATH] = "";
    DWORD len = MAX_PATH;
    if (handle)
    {
        QueryFullProcessImageName(handle, 0, s, &len);
        std::cout << s;
    }
    if (handle)
        CloseHandle(handle);
    return 0;
}
#包括
#包括
#包括
#包括
布尔设置特权(
句柄hToken,//令牌句柄
LPCTSTR权限,//启用/禁用权限
BOOL-bEnablePrivilege//TRUE表示启用。FALSE表示禁用
)
{
令牌特权tp={0};
//将所有内容初始化为零
路易斯·路易斯;
DWORD cb=sizeof(令牌特权);
if(!LookupPrivilegeValue(NULL、Privilege和luid))
返回FALSE;
tp.privilegecont=1;
tp.Privileges[0]。Luid=Luid;
if(bEnablePrivilege){
tp.Privileges[0]。Attributes=SE_PRIVILEGE_ENABLED;
}
否则{
tp.Privileges[0]。属性=0;
}
AdjustTokenPrivileges(hToken、FALSE和tp、cb、NULL、NULL);
如果(GetLastError()!=错误\u成功)
{

std::如果有机会,我不能尝试调用OpenProcess。出于好奇,为什么?@Dai我基本上是想验证在我的安全环境中创建的进程是否是真正的windows应用程序,因为windows有时会在某些地方创建随机进程。谢谢你的回答!我会在有机会时尝试。嗯,OpenProcess仍然会重新启动urns 0。@User12341921您需要在管理员模式下启用并运行该程序。我已更改了代码,您可以参考它。感谢您更新代码!我尝试了它,效果很好。但是,唯一的缺点是我必须以管理员的身份运行该进程。没有管理员,是否无法获取csrss.exe路径?@User12341921是的,您可以参考到