无法获取程序来处理WM_POWERBROADCAST消息

时间:2019-02-20 00:19:27

标签: c++ windows network-programming windows-messages

我有一个要自动在WM_POWERBROADCAST消息上终止的程序。但是由于某种原因,当我使计算机进入睡眠状态时,它并没有终止。该程序应该有足够的时间来响应此调用,但是我认为该程序根本没有在处理消息。我相信这主要是因为该程序也不会在计算机恢复时终止,并且该消息至少应该在窗口的队列中。

我做错了什么导致我的程序无法处理此消息?

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_POWERBROADCAST:
        DestroyWindow(hWnd);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    case WM_CLOSE:
        return 0;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    //Set title of program
    //SetConsoleTitleA("Star");
    //FreeConsole();

    //Change the current directory of the program back to the appropriate folder
    wchar_t* UserProf;
    SHGetKnownFolderPath(FOLDERID_Profile, 0, NULL, &UserProf);
    const wchar_t* EndProf = L"\\AppData\\UserUpdates";
    wcsncat(UserProf, EndProf, 23);
    wstring ws(UserProf);
    string wstr(ws.begin(), ws.end());
    //cout << wstr << endl;
    SetCurrentDirectoryA(wstr.c_str());

    WNDCLASSW WindowClass{CS_NOCLOSE, WindowProc, 0, 0, hInstance, NULL, LoadCursor(nullptr, IDC_ARROW), NULL, NULL, L"chakra"};

    RegisterClass(&WindowClass);

    HWND hWnd = CreateWindow(L"chakra", L"star", WS_POPUP, 0, 0, 10, 10, NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, SW_HIDE);

    string ipAddress = "10.0.0.201"; //IP address of my computer on local network
    int port = 13777;
Hunter:
    WSAData data;
    WORD ver = MAKEWORD(2, 2);
    int wsResult = WSAStartup(ver, &data);
    if (wsResult != 0) {
        //cerr << "Can't start Winsock, Err#" << wsResult << endl;
        return 0;
    }

    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET) {
        //cerr << "Can't create socket" << endl;
        return 0;
    }

    sockaddr_in hint;
    hint.sin_family = AF_INET;
    hint.sin_port = htons(port);
    inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
    int connCounter = 0;

    //Constantly attempts to connect to server
    do {
        int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
        if (connResult == SOCKET_ERROR) {
            connCounter = 0;
            closesocket(sock);
            WSACleanup();
            goto Hunter;
        }
        else {
            connCounter = 1;
        }
    } while (connCounter == 0);

    char buf[1024]; //Where message from server will be stored
    char* pbuf{ buf };

    //Things to compare

    const char* CreateAccount = "create"; //Server tells client to make IG account
    const char* CheckStatus = "check"; //Client tells server if account is running or not
    const char* Info = "info"; //Client sends Username and Password of account to server
    const char* Run = "run"; //Tells client to start running the account
    const char* Kill = "kill"; //Kills program on client for around a month
    const char* Settings = "settings"; //Server sets settings for account to run on
    string TryAgain = "#13 Not a valid input, either type [check] to check if the account is running, type [create] to create new account, or type [info] for account information\n";
    string accInfoSuccess = "#777 You have successfully entered the information for the account (^.^)\n";
    string settingsInfoSuccess = "#777 You have successfully set the settings for this account (^.^)\n";
    string accInfoProblem = "#13 There was a problem in either saving the information to this account or the account creation program. Type [create] and try again (T.T)\n";
    string settingsInfoProblem = "#13 There was a problem in saving the account settings. Type [settings] and try again (T.T)\n";
    string accRun = "#777 The account is currently running! ~(^.^)~\n";
    string accNoRun = "#13 Sorry the account isn't running, type [run] to run the account (O.o)\n";
    string accNoInfo = "#13 There is no info for an account that can be run. Type [create] to make information (\".\")\n";
    string accRunErr = "#13 There is a problem with opening the main bot program, try again. If this problem persists, there is an issue clientside V(T.T)V\n";

    int loopCounter = 0;


    //int on = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)TRUE, sizeof(TRUE));

    MSG Msg = { 0 };

    do {
        ZeroMemory(buf, 1024);

        u_long block = 0;
        ioctlsocket(sock, FIONBIO, &block);
        DWORD timeout = 500;
        setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
        //setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));

        int bytesReceived = recv(sock, buf, 1024, 0);
        if (bytesReceived > 0) {
            //Check to see if it equals one of the strings above
            if (strstr(pbuf, CreateAccount)) {
                //Run program to create account
                int accountSuccess;
                accountSuccess = accountCreation(sock);
                if (accountSuccess == 0) {
                    int sendResult = send(sock, accInfoSuccess.c_str(), accInfoSuccess.size() + 1, 0);

                }
                else {
                    int sendResult = send(sock, accInfoProblem.c_str(), accInfoProblem.size() + 1, 0);
                }
            }
            else if (strstr(pbuf, Settings)) {
                int settingsSuccess;
                settingsSuccess = settingsCreation(sock);
                if (settingsSuccess == 0) {
                    int sendResult = send(sock, settingsInfoSuccess.c_str(), settingsInfoSuccess.size() + 1, 0);

                }
                else {
                    int sendResult = send(sock, settingsInfoProblem.c_str(), settingsInfoProblem.size() + 1, 0);
                }
            }
            else if (strstr(pbuf, CheckStatus)) {
                //Check to see if program that runs account is running
                int accountSuccess = isRunning();
                if (accountSuccess == 0) {
                    int sendResult = send(sock, accRun.c_str(), accRun.size() + 1, 0);

                }
                else if (accountSuccess == 1){
                    int sendResult = send(sock, accNoRun.c_str(), accNoRun.size() + 1, 0);

                }
                else {
                    int sendResult = send(sock, accNoInfo.c_str(), accNoInfo.size() + 1, 0);

                }
            }
            else if (strstr(pbuf, Info)) {
                //Read text file containing account info and send to server
                int infoChecker = checkInfo(sock);
                if (infoChecker != 0) {
                    int sendResult = send(sock, accNoInfo.c_str(), accNoInfo.size() + 1, 0);

                }
            }
            else if (strstr(pbuf, Run)) {
                //Runs the account running program
                int running = runProg();
                if (running == 0) {
                    int sendResult = send(sock, accRun.c_str(), accRun.size() + 1, 0);
                }
                else {
                    int sendResult = send(sock, accRunErr.c_str(), accRunErr.size() + 1, 0);
                }
            }
            else if (strstr(pbuf, Kill)) {
                //Kills this program
                WSACleanup();
                return 0;
            }
            else {
                //Send back to server that the wrong thing was inputted
                int sendResult = send(sock, TryAgain.c_str(), TryAgain.size() + 1, 0);
                ZeroMemory(buf, 1024);
                loopCounter = 0;
            }
        }
        else {
            //Check to make sure bot is running
            int vroom = isRunning();
            if (vroom == 1) {
                //runProg();
                loopCounter = 0;
            }
            else {
                loopCounter = 0;
            }
        }

        if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE) != 0) {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }

    } while (loopCounter == 0);

    WSACleanup();
    return 0; 
}

1 个答案:

答案 0 :(得分:0)

显示的代码有很多问题,但是让我们从影响消息问题的最重要的问题开始-所有 thread-blocking 套接字代码都不属于您的{ {1}} 完全,更不用说消息循环本身了。这就是为什么您处理WinMain()之类的窗口消息的速度如此之慢的原因。

您需要重组代码。要么:

  • 将套接字代码移动到工作线程,并使其阻塞所有想要的线程。

  • 使用异步套接字I / O(通过WM_POWERBROADCAST等),您可以在WSAAsyncSelect()内部进行处理。或使用重叠的I / O。无论哪种方式,都不需要线程或阻塞操作。

无论您做什么,都不要阻止WindowProc的消息循环。

话虽如此,您代码的其他问题还包括:

  • WinMain()未定义的行为SHGetKnownFolderPath(..., &UserProf); wcsncat(UserProf, EndProf, 23);没有为您分配足够的内存来附加任何内容。您需要分配另一个缓冲区,该缓冲区必须足以将SHGetKnownFolderPath()复制到UserProf并附加到其中。或者,只需先将EndProf转换为UserProf,然后将std::wstring附加到末尾(无论哪种方式,完成后都不要忘记释放EndProf它-您当前正在泄漏它。)

  • 您不应将自定义UserProf子文件夹直接添加到用户的UserUpdates文件夹本身。使用AppDataFOLDERID_LocalAppData/LowFOLDERID_RoamingAppData来获得一个更合适的文件夹,将您的内容添加到其中。

  • FOLDERID_ProgramData不是将string wstr(ws.begin(), ws.end());转换为std::wstring的正确方法。请改用std::stringstd::wstring_convert或其他类似的转换方法。或者,根本不进行转换,而是使用WideCharToMultiByte()std::wcout

  • 您滥用SetCurrentDirectoryW()。在SO_REUSEADDR / bind()之后,它毫无用处,而且您甚至都无法正确启用它。

  • connect()不会像您期望的那样返回以空值结尾的数据。在试图匹配接收到的字符串的代码中,您可能会遇到不希望的副作用,即使不是崩溃也是如此。 TCP是面向流的,而不是像您认为的那样面向消息的。在StackOverflow上有很多帖子,展示了正确的方法来处理基于TCP的I / O。

话虽如此,请尝试以下类似操作:

recv()