如何在 Win 7 中为 C 中的 windows 服务检索系统代理设置

How to retrieve system proxy settings in Win 7 for windows service in C

我正在编写一个应用程序,它将 运行 作为一项服务,并将选择系统代理设置以与外界通信。我试过 WinHttpGetIEProxyConfigForCurrentUser 但它无法检索当前用户的代理设置这是显而易见的,因为服务 运行ning 在本地系统域下。为了实现同样的目标,我必须让用户登录到我不希望应用程序用户执行的服务。我读到了可以传递给 CreateService() 的 SERVICE_USER_OWN_PROCESS 参数,但我既没有在 WinNT.h 中找到它的声明,也不确定它是否有效。由于这个问题,应用程序的开发被卡住了。谁能帮帮忙

我在当前用户的上下文中遇到了与 运行 程序类似的情况。

首先 - 在全局范围内的某个地方 - 定义以下变量:

 HANDLE hUsrToken;
 HANDLE hDupToken;
 int sessionId;

您需要获取当前用户的session Id:

int getInteractiveSessinoId()
{
    PWTS_SESSION_INFO pSessInfo;
    ulong count;                    // Number of current user sessions
    int result = -1;

    if (!WTSEnumerateSessions(WTS_CURRENT_SERVER, 0, 1, &pSessInfo, &count))
    {
        printf("Getting session information failed with error %d\n", << GetLastError());
        WTSFreeMemory(pSessInfo);
        return -2;
    }

    for (ulong loop = 0; loop < count; loop++)
    {
        if (pSessInfo[loop].State == WTSActive)
        {
            printf("Session %d is currently active\n", pSessInfo[loop].SessionId);
            result = pSessInfo[loop].SessionId;
            break;
        }
    }

    WTSFreeMemory(pSessInfo);
    return result;
}

接下来需要模拟当前用户(我称之为"attach to the session"):

bool attachToSession(int sessionId)
{
    // We need to duplicate the token of the session's user
    if (!WTSQueryUserToken(sessionId, &hUsrToken))
    {
        pritnf("Query the user token failed with error %d\n", GetLastError());
        return false;
    }

    if (!DuplicateTokenEx(hUsrToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenImpersonation , &hDupToken))
    {
        printf("Duplicating a token failed with error %d\n", GetLastError());
        return false;
    }

    if (!ImpersonateLoggedOnUser(hDupToken))
    {
        printf("Impersonating the user failed with error %d\n", GetLastError();
        return false;
    }

    return true;
}

现在在当前用户的上下文中做任何您想做的事情,完成后,从用户的上下文中恢复(或"detach"):

bool detachFromSession()
{
    if (!RevertToSelf())
    {
        printf("Reverting the token failed with error %d\n", GetLastError());
        return false;
    }

    (void)CloseHandle(hDupToken);
    (void)CloseHandle(hUsrToken);

    return true;
}

我不确定将令牌应用于当前(服务)线程是否是个好主意。我认为创建一个新线程是一个更好的主意,该线程在用户的上下文中执行您想做的任何事情并将模拟令牌应用于它。所以您的代码部分可能如下所示:

HANDLE hUsrToken;
HANDLE hDupToken;
HANDLE hThread;
int sessionId;
DWORD threadId;

DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
    // WinHttpGetIEProxyConfigForCurrentUser(...
}

sessionId = getInterActiveSessionId();

if (attachToSession(int sessionId) == false)
{
    // Error handling
    return;
}

hThread = CreateThread(NULL,                   // default security attributes
                       0,                      // use default stack size                       
                       MyThreadFunction,       // thread function name
                       NULL,                   // argument to thread function 
                       CREATE_SUSPENDED,       // Delay execution
                       &threadId);

if (SetThreadToken(hThread, hDupToken) == false)
{
    // Error handling
    return;
}

ResumeThread(hThread);

我不能保证这会解决您的问题,但我希望它能解决。祝你好运!