原生C ++ node.js模块插件WinHttp Detect Auto Proxy Config Url Error return

时间:2018-11-23 13:54:11

标签: c++ node.js proxy winhttp

我陷入了困境,我需要一些C ++代码的帮助。这是我第一次尝试使用C ++,它主要是出于必要而诞生的。

我正在尝试(感觉没有成功)为Node.JS构建本机NAN模块,该模块将由Windows上的Electron应用程序使用。

当用户代理配置设置为自动检测时,我需要它返回WinHttpDetectAutoProxyConfigUrl。

我已经在C#中为另一个应用程序构建了这个确切的东西,它可以在我们的分布式用户BYOD环境中无缝运行。但是,在这种情况下,我不想不必要地依赖于dot.net框架。

当我谈到C ++时,很了解我,因为多年来我的大部分知识都是理论上的。我希望每天实际使用C ++的人都能查看我的代码,并帮助纠正正在发生的错误。

我一直在尝试使用VSCode中的“ std :: cout”进行调试。

从图像底部的输出中可以看到,其中的一些似乎正在运行,并且代码已按预期放入“获取自动URL” IF块中。但是输出非常不规则(“ ...”),与我期望看到的wpad.dat URL(从Winhttp.dll实现的wpad协议返回)完全不同。

我的问题: 好像结果为空白,然后将“ char buffer [2083];”发送到stdOut,并且所有字符均编码错误。

对此的任何帮助将非常有帮助,在此先感谢。

请参见下面的代码。

main.cpp

#include <nan.h>
#include <Windows.h>
#include <Winhttp.h>
#include <iostream>

#pragma comment(lib, "winhttp.lib")

using namespace std;

// NAN_METHOD is a Nan macro enabling convenient way of creating native node functions.
// It takes a method's name as a param. By C++ convention, I used the Capital cased name.
NAN_METHOD(AutoProxyConfigUrl) {

    cout << "AutoProxyConfigUrl" << "\n"; 

    v8::Isolate* isolate = info.GetIsolate(); // args.GetIsolate();

    LPWSTR strConfigUrl = NULL;
    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG MyProxyConfig;

    if(!WinHttpGetIEProxyConfigForCurrentUser(&MyProxyConfig))
    { 
        //check the error DWORD Err = GetLastError(); 
        DWORD Err = GetLastError(); 
        cout << "WinHttpGetIEProxyConfigForCurrentUser failed with the following error number: " << Err << "\n";
        switch (Err) 
        {
            case ERROR_FILE_NOT_FOUND: 
            cout << "The error is ERROR_FILE_NOT_FOUND" << "\n"; 
            break; 
            case ERROR_WINHTTP_INTERNAL_ERROR:
            cout << "ERROR_WINHTTP_INTERNAL_ERROR" << "\n"; 
            break; 
            case ERROR_NOT_ENOUGH_MEMORY:
            cout << "ERROR_NOT_ENOUGH_MEMORY" << "\n"; 
            break; 
            default: 
            cout << "Look up error in header file." << "\n"; 
            break; 
        }//end switch 

        //TODO this might not be a good idea but it is worth trying
        strConfigUrl = L"http://wpad/wpad.dat"; //Default to Fallback wpad 

    }//end if 
    else 
    { 
        //no error so check the proxy settings and free any strings 
        cout << "Auto Detect is: " << MyProxyConfig.fAutoDetect <<  "\n"; 

        if(MyProxyConfig.fAutoDetect){

             cout << "Get Auto URL" <<  "\n"; 

            if (!WinHttpDetectAutoProxyConfigUrl(WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A, &strConfigUrl))
            {
                cout << "Error getting URL" <<  "\n"; 

                //This error message is not necessarily a problem and can be ignored if you are using direct connection. you get this error if you are having direct connection.
                //check the error DWORD Err = GetLastError(); 
                DWORD Err = GetLastError(); 
                if (ERROR_WINHTTP_AUTODETECTION_FAILED == Err)
                {
                    strConfigUrl = L"http://wpad/wpad.dat"; //Default to Fallback wpad 
                }

                //TODO work out what to do with the other errors

            }
        }

        if(NULL != MyProxyConfig.lpszAutoConfigUrl) 
        { 
            wcout << "AutoConfigURL (MyProxyConfig.lpszAutoConfigUrl) is: " << MyProxyConfig.lpszAutoConfigUrl << "\n"; 
            GlobalFree(MyProxyConfig.lpszAutoConfigUrl);
        }

        if(NULL != MyProxyConfig.lpszProxy) 
        { 
            wcout << "AutoConfigURL (MyProxyConfig.lpszProxy) is: " << MyProxyConfig.lpszProxy << "\n";
            GlobalFree(MyProxyConfig.lpszProxy);
         }

        if(NULL != MyProxyConfig.lpszProxyBypass) 
        {
            wcout << "AutoConfigURL is: " << MyProxyConfig.lpszProxyBypass << "\n";                      
            GlobalFree(MyProxyConfig.lpszProxyBypass); 
        }
    }//end else 

     //cout << "strConfigUrl" << strConfigUrl << "\n"; 

    char buffer[2083];
    wcstombs( buffer, strConfigUrl, wcslen(strConfigUrl) ); // Need wcslen to compute the length of the string

    // convert it to string
    std::string returnUrl(buffer);  

    // Create an instance of V8's String type
    auto message = Nan::New(returnUrl).ToLocalChecked();

    // 'info' is a macro's "implicit" parameter - it's a bridge object between C++ and JavaScript runtimes
    // You would use info to both extract the parameters passed to a function as well as set the return value.
    info.GetReturnValue().Set(message);

    if(strConfigUrl)
        GlobalFree(strConfigUrl);

}   

// Module initialization logic
NAN_MODULE_INIT(Initialize) {
    // Export the `Hello` function (equivalent to `export function Hello (...)` in JS)
    NAN_EXPORT(target, AutoProxyConfigUrl);
}

// Create the module called "addon" and initialize it with `Initialize` function (created with NAN_MODULE_INIT macro)
NODE_MODULE(proxyautodetect, Initialize);

main.js

// note that the compiled addon is placed under following path
//const {AutoProxyConfigUrl} = require('./build/Release/proxyautodetect.node');
const {AutoProxyConfigUrl} = require('./build/Debug/proxyautodetect.node');

// `Hello` function returns a string, so we have to console.log it!
console.log(AutoProxyConfigUrl());

构建并运行输出:

C:\Code\Work\wpad-auto-detect>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild --debug )  else (node "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" rebuild --debug )
Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
  main.cpp
  win_delay_load_hook.cc
     Creating library C:\Code\Work\wpad-auto-detect\build\Debug\proxyautodetect.lib and object C:\Code\Work\wpad-auto-detect\build\Debug\proxyautodet
  ect.exp
  proxyautodetect.vcxproj -> C:\Code\Work\wpad-auto-detect\build\Debug\\proxyautodetect.node
PS C:\Code\Work\wpad-auto-detect> npm start

> proxyautodetect@1.0.0 start C:\Code\Work\wpad-auto-detect
> node main.js

AutoProxyConfigUrl
Auto Detect is: 1
Get Auto URL
"
"��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1��J╗
PS C:\Code\Work\wpad-auto-detect>

Image of code output

1 个答案:

答案 0 :(得分:0)

我做了一些修整

   int urlLen = wcslen(strConfigUrl) ;

#if DEBUG
    cout << "strConfigUrl wcslen : " << urlLen << "\n";      
#endif 

    char buffer[2083]; //This is the max length a URL can be in IE
    wcstombs( buffer, strConfigUrl, wcslen(strConfigUrl) ); // Need wcslen to compute the length of the string

    // convert it to string
    std::string returnUrl(buffer);  

    // Create an instance of V8's String type and Return only the Length needed so kind of Trim the extra char
    auto message = Nan::New(returnUrl.substr(0, urlLen)).ToLocalChecked();