zoukankan      html  css  js  c++  java
  • 设置与获取系统代理信息

    设置与读取上图中的脚本地址,用于HTTP请求与下载时可以走代理环境

    头文件

    #include"wininet.h"
    #pragma comment(lib, "Wininet.lib")

    给系统设置代理信息

    #if defined(OS_WIN)
     
    BOOL SetSystemProxyFromPacUrl(wchar_t* conn_name, wchar_t* proxy_full_addr) {
        //conn_name: active connection name.
        //proxy_full_addr : eg "210.78.22.87:8000"
        INTERNET_PER_CONN_OPTION_LISTW list;
        BOOL bReturn;
        DWORD dwBufSize = sizeof(list);
     
        // Fill out list struct.
        list.dwSize = sizeof(list);
     
        // NULL == LAN, otherwise connectoid name.
        list.pszConnection = conn_name;
     
        // Set three options.
        list.dwOptionCount = 2;
        list.pOptions = new INTERNET_PER_CONN_OPTIONW[2];
     
        // Make sure the memory was allocated.
        if (NULL == list.pOptions) {
            // Return FALSE if the memory wasn't allocated.
            LOG_ERROR << "failed to allocat memory in SetConnectionOptions()";
            return FALSE;
        }
     
        // Set flags.
        list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
         list.pOptions[0].Value.dwValue = PROXY_TYPE_AUTO_PROXY_URL;
     
        // Set proxy name.
        list.pOptions[1].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
        list.pOptions[1].Value.pszValue = proxy_full_addr;
     
        // Set the options on the connection.
        bReturn = InternetSetOption(NULL,
                       INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
     
        // Free the allocated memory.
        delete[] list.pOptions;
     
        InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
        InternetSetOption(NULL, INTERNET_OPTION_REFRESH, NULL, 0);
     
        return bReturn;
    }
    #else
    bool SetSystemProxyFromPacUrl(const std::string& pacUrl) {
        if (!base::dbus::CallMethodWithNoResult(
            base::dbus::Type::kSession, "com.deepin.daemon.Network", "SetAutoProxy", pacUrl)) {
            LOG_ERROR << "SetAutoProxy call failed.";
            return false;
        }
        return base::dbus::CallMethodWithNoResult(
            base::dbus::Type::kSession, "com.deepin.daemon.Network", "SetProxyMethod", "auto");
    }
    #endif

    读取系统设置代理信息

    方式1:

    BOOL QueryProxy() {
        BOOL ret = FALSE;
     
        INTERNET_PER_CONN_OPTION_LIST List;
        INTERNET_PER_CONN_OPTION Option[5];
     
        unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
     
        Option[0].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
        Option[1].dwOption = INTERNET_PER_CONN_AUTODISCOVERY_FLAGS;
        Option[2].dwOption = INTERNET_PER_CONN_FLAGS;
        Option[3].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
        Option[4].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
     
        List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
        List.pszConnection = NULL;
        List.dwOptionCount = 5;
        List.dwOptionError = 0;
        List.pOptions = Option;
     
        if (!InternetQueryOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize))
            _tprintf(_T("InternetQueryOption failed! (%d)
    "), GetLastError());
        if (Option[0].Value.pszValue != NULL)
            _tprintf(_T("%s
    "), Option[0].Value.pszValue);
        if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL) == PROXY_TYPE_AUTO_PROXY_URL)
            _tprintf(_T("PROXY_TYPE_AUTO_PROXY_URL
    "));
        if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_DETECT) == PROXY_TYPE_AUTO_DETECT)
            _tprintf(_T("PROXY_TYPE_AUTO_DETECT
    "));
        if ((Option[2].Value.dwValue & PROXY_TYPE_PROXY) == PROXY_TYPE_PROXY) {
            _tprintf(_T("Proxy ENABLED!
    "));
            ret = TRUE;
        } else _tprintf(_T("Proxy DISABLED!
    "));
     
        _tprintf(_T("Current proxy:%s
    "), Option[4].Value.pszValue);
     
        INTERNET_VERSION_INFO Version;
        nSize = sizeof(INTERNET_VERSION_INFO);
     
        InternetQueryOption(NULL, INTERNET_OPTION_VERSION, &Version, &nSize)
        if (Option[0].Value.pszValue != NULL)
            GlobalFree(Option[0].Value.pszValue);
        if (Option[3].Value.pszValue != NULL)
            GlobalFree(Option[3].Value.pszValue);
        if (Option[4].Value.pszValue != NULL)
            GlobalFree(Option[4].Value.pszValue);
        return ret;
    }

    方式2:

    BOOL GetWinetProxy(LPSTR lpszProxy, UINT nProxyLen) {
        //unsigned long nSize = 4096;
        //char szBuf[4096] = { 0 };
        //INTERNET_PROXY_INFO* pProxyInfo = (INTERNET_PROXY_INFO*)szBuf;
        //if (!InternetQueryOption(NULL, INTERNET_OPTION_PROXY, pProxyInfo, &nSize)) {
        // return FALSE;
        //}
        //if (pProxyInfo->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) {
        // return FALSE;
        //}
     
        ////这里是代理列表,以分隔,结束处两个,一般我们取第一条代理就够了
        //LPCSTR lpszProxyList = (LPCSTR)(pProxyInfo + 1);
        //int nLen = strlen(lpszProxyList);
        //if (lpszProxy) {
        // nProxyLen = min(nLen, nProxyLen - 1);
        // strncpy_s(lpszProxy, nProxyLen + 1, lpszProxyList, nLen);
        // lpszProxy[nProxyLen] = 0;
        //}
        //return nLen;
     
     
        // 方法2
        INTERNET_PER_CONN_OPTION_LISTA List;
        INTERNET_PER_CONN_OPTIONA Option[1];
        unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LISTA);
        Option[0].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
     
        List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
        List.pszConnection = NULL;
        List.dwOptionCount = 1;
        List.dwOptionError = 0;
        List.pOptions = Option;
     
        if (!InternetQueryOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) {
            return FALSE;
        }
     
        if (Option[0].Value.pszValue != NULL) {
            int nLen = strlen(Option[0].Value.pszValue);
            if (lpszProxy) {
                nProxyLen = min(nLen, nProxyLen - 1);
                strncpy_s(lpszProxy, nProxyLen + 1, Option[0].Value.pszValue, nProxyLen);
                lpszProxy[nProxyLen] = 0;
            }
            GlobalFree(Option[0].Value.pszValue);
            return nLen;
        }
        return FALSE;
    }

     

    (看到上面的辣么多方法,系不系狠鸡冻。别急着拷代码,先看完“使用说明”)
    神坑、巨坑、无底洞--以上的方式只适用于用户进程、管理员进程;不适用于服务进程!!!

    原因:从微软官方文档看,当程序时服务时,Microsoft Win32 Internet将不给予支持。即wininet.h、wininet.lib不能适用

    链接:

    https://docs.microsoft.com/zh-cn/troubleshoot/browsers/wininet-not-supported-in-services

    https://docs.microsoft.com/en-us/windows/win32/api/wininet/ns-wininet-internet_per_conn_optiona

    本质原因:上述的方法,无论API获取还是查询代理列表,都是读取注册表。但是这些信息都存在于“HKEY_CURRENT_USER”根目录下。即服务进程无法读取或写入的目录

    如图:

    解决方法:

    (一)模拟一个普通用户登陆,可以操作 HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersion

    (二) 获取 SID,操作HKEY_CURRENT_USER被重定向到 HKEY_USERS 的值。

    参考链接:https://blog.csdn.net/zhouguangcai8/article/details/28280449

    方法1实现:

    #if defined(OS_WIN)
    #include <windows.h>
    #include <Wtsapi32.h>
    #include <UserEnv.h>
    #pragma comment(lib, "WtsApi32.lib")
    #pragma comment(lib,"Userenv.lib")
    #pragma comment(lib, "WtsApi32.lib")
    #endif
     
    bool GetSystemProxyUrl(std::string& proxyUrl) {
        HANDLE hToken = NULL;
        BOOL bImpersonated = FALSE;
        PROFILEINFOA cuProfileInfo;
        TCHAR szUsername[MAX_PATH];
        DWORD dwUsernameLen = MAX_PATH;
        DWORD seesionid = WTSGetActiveConsoleSessionId();
        bool isSuccess = false;
        if (WTSQueryUserToken(seesionid, &hToken)) {
            if (ImpersonateLoggedOnUser(hToken)) {
                bImpersonated = TRUE;
            }
     
            if (!GetUserName(szUsername, &dwUsernameLen)) {
                LOG_WARN << "Failed to GetUserName.errCode:" << std::to_string(GetLastError());
                return false;
            }
     
            memset(&cuProfileInfo, 0, sizeof(cuProfileInfo));
            cuProfileInfo.dwSize = sizeof(PROFILEINFOA);
            cuProfileInfo.lpUserName = szUsername;
            cuProfileInfo.dwFlags = 1;
     
            if (bImpersonated) {
                RevertToSelf();
                bImpersonated = FALSE;
            }
     
            HKEY hKey;
            char szTmp[256] = { 0 };
            if (LoadUserProfile(hToken, &cuProfileInfo)) {
                LONG lRet = RegOpenKeyEx((struct HKEY__ *)cuProfileInfo.hProfile,
                                         "Software\Microsoft\Windows\CurrentVersion\Internet Settings",
                                         0, KEY_ALL_ACCESS, &hKey);
                if (lRet == ERROR_SUCCESS) {
                    DWORD dwLen = 255;
                    RegQueryValueEx(hKey, "AutoConfigURL", NULL, NULL, (unsigned char*)szTmp, &dwLen);
                    if (szTmp[0] != 0) {
                        proxyUrl = std::string(szTmp);
                        isSuccess = true;
                    }
                    RegCloseKey(hKey);
                }else {
                    LOG_WARN << "Failed to RegOpenKeyEx.errCode:" << std::to_string(GetLastError());
                }
            } else {
                LONG lRet = RegOpenKeyEx(HKEY_CURRENT_USER,
                               "Software\Microsoft\Windows\CurrentVersion\Internet Settings",
                                0, KEY_ALL_ACCESS, &hKey);
                if (lRet == ERROR_SUCCESS) {
                    DWORD dwLen = 255;
                    RegQueryValueEx(hKey, "AutoConfigURL", NULL, NULL, (unsigned char*)szTmp, &dwLen);
                    if (szTmp[0] != 0) {
                        proxyUrl = std::string(szTmp);
                        isSuccess = true;
                    }
                    RegCloseKey(hKey);
                }else {
                    LOG_WARN << "Failed to LoadUserProfile and RegOpenKeyEx.errCode:" << std::to_string(GetLastError());
                }
            }
        }
        return isSuccess ? true : false;
    }
     
     
     
     
     
     
  • 相关阅读:
    Spring 框架的设计理念与设计模式分析
    stratos paas平台
    云计算国际标准
    如何在KVM中管理存储池
    深度学习(四) softmax函数
    深度学习(二)BP求解过程和梯度下降
    深度学习(一) BP神经网络
    提交代码到git
    Mac 安装tensorflow
    Mac 安装Git
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/15028094.html
Copyright © 2011-2022 走看看