Не удается получить программу для обработки сообщения WM_POWERBROADCAST - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть программа, которую я хочу автоматически завершить в сообщении 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 голосов
/ 20 февраля 2019

Есть ТОП проблем с показанным кодом, но давайте начнем с самого важного, который влияет на проблему вашего сообщения - все это блокирующий поток код сокета не принадлежит вашему WinMain() вообще , не говоря уже о внутри самой петли сообщений .Вот почему ваша обработка оконных сообщений, таких как WM_POWERBROADCAST, выполняется так медленно.

Вам необходимо реструктурировать свой код.Либо:

  • переместить код сокета в рабочий поток и позволить ему блокировать этот поток все, что ему нужно.

  • использовать асинхронный сокет I /O (через WSAAsyncSelect() и т. Д.), Который вы можете обработать внутри вашего WindowProc.Или используйте перекрывающийся ввод / вывод.В любом случае, операции с потоками или блокировкой не требуются.

Что бы вы ни делали, НЕ блокируйте цикл сообщений WinMain().

При этом другие проблемыс вашим кодом включите:

  • SHGetKnownFolderPath(..., &UserProf); wcsncat(UserProf, EndProf, 23); - это неопределенное поведение .SHGetKnownFolderPath() не выделяет достаточно памяти для добавления чего-либо.Вам нужно выделить другой буфер, достаточно большой, чтобы скопировать UserProf в и добавить EndProf в.Или просто преобразуйте UserProf в std::wstring сначала, а затем добавьте EndProf в конце этого (в любом случае, не забудьте освободить UserProf, когда вы закончите с ним - вы в настоящее время его утечка).

  • Вы не должны добавлять свою пользовательскую подпапку UserUpdates напрямую в саму пользовательскую папку AppData.Вместо этого используйте FOLDERID_LocalAppData/Low, FOLDERID_RoamingAppData или FOLDERID_ProgramData, чтобы получить более подходящую папку для добавления своих вещей.

  • string wstr(ws.begin(), ws.end()); не является правильным способом преобразования std::wstring до std::string.Вместо этого используйте std::wstring_convert, WideCharToMultiByte() или другое подобное преобразование.Или просто вообще не конвертируйте, вместо этого используйте std::wcout и SetCurrentDirectoryW().

  • вы неправильно используете SO_REUSEADDR.Это бесполезно после bind() / connect(), и вы все равно даже не включаете его должным образом.

  • recv() не возвращает данные с нулевым символом в конце, как вы ожидаете.Вы, вероятно, испытаете нежелательные побочные эффекты, если не все сбои, в вашем коде, который пытается сопоставить полученные строки.TCP ориентирован на поток, а не на сообщения, как вы думаете.В StackOverflow имеется множество публикаций, в которых демонстрируется правильный способ обработки операций ввода-вывода через TCP.

С учетом всего сказанного попробуйте что-то еще подобное:

HWND hMyWnd = NULL;
HANDLE hThread = NULL;
bool stopThread = false;

int readString(SOCKET sock, char *buf, int buflen, string &str)
{
    str.clear();

    char ch, *pbuf = buf;
    int len = 0, bytesReceived;

    do {
        if (stopThread)
            return -2;

        bytesReceived = recv(sock, &ch, 1, 0);

        if (bytesReceived == -1) {
            if ((WSAGetLastError() != WSAETIMEDOUT) || !str.empty()) {
                //cerr << "Can't read from socket, Err#" << WSAGetLastError() << endl;
                return -1;
            }
            return 1;
        }

        if (bytesReceived == 0) {
            //cerr << "Socket disconnected by server" << endl;
            return 0;
        }

        if (ch == '\0')
            break;

        *pbuf++ = ch;
        len += bytesReceived;

        if (len == buflen) {
            str.append(buf, len);
            pbuf = buf;
            len = 0;
        }
    }
    while (true);

    if (len > 0)
        str.append(buf, len);

    return 1;
}

int sendString(SOCKET sock, const string &str)
{
    const char *pbuf = str.c_str();
    int len = str.length() + 1, bytesSent;

    do {
        if (stopThread)
            return -2;

        bytesSent = send(sock, pbuf, len, 0);

        if (bytesSent == -1) {
            //cerr << "Can't send to socket, Err#" << WSAGetLastError() << endl;
            return -1;
        }

        pbuf += bytesSent;
        len -= bytesSent;
    }
    while (len > 0);

    return 1;
}

//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

//Things to send
const 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";
const string accInfoSuccess = "#777 You have successfully entered the information for the account (^.^)\n";
const string settingsInfoSuccess = "#777 You have successfully set the settings for this account (^.^)\n";
const 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";
const string settingsInfoProblem = "#13 There was a problem in saving the account settings. Type [settings] and try again (T.T)\n";
const string accRun = "#777 The account is currently running! ~(^.^)~\n";
const string accNoRun = "#13 Sorry the account isn't running, type [run] to run the account (O.o)\n";
const string accNoInfo = "#13 There is no info for an account that can be run. Type [create] to make information (\".\")\n";
const 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";

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    string ipAddress = "10.0.0.201"; //IP address of my computer on local network
    int port = 13777;

    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;
    }

    sockaddr_in hint = {};
    hint.sin_family = AF_INET;
    hint.sin_port = htons(port);
    inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);

    SOCKET sock = INVALID_SOCKET;
    char buf[1024]; //Where message from server will be stored
    string str;

    while (!stopThread) {

        //attempt to connect to server

        sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == INVALID_SOCKET) {
            //cerr << "Can't create socket, Err#" << WSAGetLastError() << endl;
            break;
        }

        //BOOL on = TRUE;
        //setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));

        //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));

        wsResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
        if (wsResult != SOCKET_ERROR) {
            do {
                wsResult = readString(sock, buf, sizeof(buf), str);
                if (wsResult <= 0)
                    break;

                if (!str.empty()) {
                    //Check to see if it equals one of the strings above
                    if (str == CreateAccount) {
                        //Run program to create account
                        if (accountCreation(sock) == 0) {
                            wsResult = sendString(sock, accInfoSuccess);
                        }
                        else {
                            wsResult = sendString(sock, accInfoProblem);
                        }
                    }
                    else if (str == Settings) {
                        if (settingsCreation(sock) == 0) {
                            wsResult = sendString(sock, settingsInfoSuccess);
                        }
                        else {
                            wsResult = sendString(sock, settingsInfoProblem);
                        }
                    }
                    else if (str == CheckStatus) {
                        //Check to see if program that runs account is running
                        int accountSuccess = isRunning();
                        if (accountSuccess == 0) {
                            wsResult = sendString(sock, accRun);
                        }
                        else if (accountSuccess == 1){
                            wsResult = sendString(sock, accNoRun);
                        }
                        else {
                            wsResult = sendString(sock, accNoInfo);
                        }
                    }
                    else if (str == Info) {
                        //Read text file containing account info and send to server
                        if (checkInfo(sock) != 0) {
                            wsResult = sendString(sock, accNoInfo);
                        }
                    }
                    else if (str == Run) {
                        //Runs the account running program
                        if (runProg() == 0) {
                            wsResult = sendString(sock, accRun);
                        }
                        else {
                            wsResult = sendString(sock, accRunErr);
                        }
                    }
                    else if (str == Kill) {
                        //Kills this program
                        PostMessage(hMyWnd, WM_CLOSE, 0, 0);
                        stopThread = true;
                        break;
                    }
                    else {
                        //Send back to server that the wrong thing was inputted
                        wsResult = sendString(sock, TryAgain);
                    }
                }
                else {
                    //Check to make sure bot is running
                    if (isRunning() == 1) {
                        //runProg();
                    }
                }
            }
            while (!stopThread);
        }

        closesocket(sock);
        sock = INVALID_SOCKET;

        if (!stopThread)
            Sleep(5000);
    }

    WSACleanup();
    return 0; 
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
        case WM_CREATE: {
            hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
            return 0;
        case WM_POWERBROADCAST:
            DestroyWindow(hWnd);
            return 0;
        case WM_DESTROY:
            if (hThread) {
                stopThread = true;
                WaitForSingleObject(hThread, INFINITE);
                CloseHandle(hThread);
                hThread = NULL;
            }
            PostQuitMessage(0);
            return 0;
        case WM_CLOSE:
            DestroyWindow(hWnd);
            return 0;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    //Change the current directory of the program back to the appropriate folder
    wchar_t* UserProf;
    if (SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &UserProf) == S_OK) {
        wstring wstr = wstring(UserProf) + L"\\UserUpdates";
        //wcout << wstr << endl;
        SetCurrentDirectoryW(wstr.c_str());
        CoTaskMemFree(UserProf);
    }

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

    if (!RegisterClassW(&WindowClass)) {
        //cerr << "Can't register window class, Err#" << GetLastError() << endl;
        return 0;
    }

    hMyWnd = CreateWindowW(L"chakra", L"star", WS_POPUP, 0, 0, 10, 10, NULL, NULL, hInstance, NULL);
    if (!hMyWnd) {
        //cerr << "Can't create window, Err#" << GetLastError() << endl;
        return 0;
    }

    ShowWindow(hMyWnd, SW_HIDE);

    MSG Msg;
    while (GetMessage(&Msg, NULL, 0, 0)) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

    return 0; 
}
...