Собственное дополнение модуля C ++ node.js WinHttp Обнаружение автоконфигурации прокси URL-адрес возврата ошибки - PullRequest
0 голосов
/ 23 ноября 2018

Я застрял в затруднительном положении, и мне нужна помощь с кодом C ++.Это моя первая попытка сделать C ++, и в этот момент она возникла в основном из-за необходимости.

Я пытаюсь (безуспешно чувствует) создать собственный модуль NAN для Node.JS, который будет использоваться приложением Electron.в Windows.

Мне нужно, чтобы он возвращал WinHttpDetectAutoProxyConfigUrl, когда для настройки прокси-сервера пользователя установлено значение Автоопределение.

Я построил эту точную вещь в C # для другого приложения, и она прекрасно работает в нашей распределенной пользовательской среде BYOD.Однако в этом случае я не хочу без необходимости зависеть от структуры dot.net.

Правильно, я знаю, насколько я знаю, когда речь заходит о C ++, так как большая часть моих знаний за эти годы до сих пор была теоретической.Я надеюсь, что кто-то, кто на самом деле ежедневно работает на C ++, сможет посмотреть на мой код и помочь исправить возникающую ошибку.

Я пытался отлаживать, используя «std :: cout» в VSCode.

Как видно из выходных данных внизу изображения, некоторые из них, кажется, работают и код помещается в блок IF «Get Auto URL», как и ожидалось.Однако выходные данные очень иритические («�����») и не похожи на URL-адрес wpad.dat, который я ожидал увидеть возвращенным из протокола wpad, реализованного winhttp.dll.

Моя проблема: Это как если бы результат был пустым, и затем в буфер stdOut отправляется «буфер символов [2083];», и все символы кодируются неправильно.

Любая помощь по этому вопросу будет очень полезна, поэтому заранее спасибо.

Пожалуйста, смотрите код ниже.

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>

Изображение вывода кода

1 Ответ

0 голосов
/ 26 ноября 2018

Я сделал своего рода обрезку

   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();
...