在我的申请继续之前等待第二个流程完成

时间:2016-12-12 19:57:11

标签: visual-studio-2015 mfc

这是我在 Visual C ++ MFC 应用程序中执行控制台应用程序的代码:

bool CGoogleAuthandSync::ExecuteProgram(CString strCommand, DWORD &rExitCode)
{
    PROCESS_INFORMATION processInformation = { 0 };
    STARTUPINFO         startupInfo = { 0 };
    int                 nStrBuffer;
    BOOL                bProcessResult, bExitCodeProcess;
    bool                bOK = false;
    CWaitCursor         wait;

    rExitCode = -1;

    startupInfo.cb = sizeof(startupInfo);
    nStrBuffer = strCommand.GetLength() + 50;

    bProcessResult = CreateProcess(NULL, strCommand.GetBuffer(nStrBuffer),
        NULL, NULL, FALSE,
        NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
        NULL, NULL, &startupInfo, &processInformation);
    strCommand.ReleaseBuffer();

    if (!bProcessResult)
    {
        // CreateProcess() failed
        // Get the error from the system
        LPVOID lpMsgBuf;
        DWORD dw = GetLastError();
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);

        // Display the error
        CString strError = (LPTSTR)lpMsgBuf;
        TRACE(_T("Authenticate failed at CreateProcess()\nCommand=%s\nMessage=%s\n\n"), strCommand, strError);

        // Free resources created by the system
        LocalFree(lpMsgBuf);

        // We failed.
        return false;
    }
    else
    {
        // Successfully created the process.  Wait for it to finish.
        //WaitForSingleObject(processInformation.hProcess, INFINITE);
        // AJT v14.0.3

        DWORD WaitResult;
        do
        {
            WaitResult = MsgWaitForMultipleObjects(1,
                // only 1 wait object
                &processInformation.hProcess, // worker thread
                FALSE,   // stop if any
                INFINITE,  // no timeout
                QS_ALLINPUT);
            if (WaitResult == WAIT_OBJECT_0 + 1)
            {
                // Handle windows message
                MSG Msg;
                while (PeekMessage(&Msg, NULL, 0, (UINT)-1, PM_REMOVE))
                {
                    TRACE3("%d %d %d\n", Msg.message, Msg.wParam, Msg.lParam);
                    TranslateMessage(&Msg);
                    DispatchMessage(&Msg);
                }
            }
        } while (WaitResult != WAIT_OBJECT_0);
        //} while (WaitResult == WAIT_OBJECT_0 + 1);
        ASSERT(WaitResult == WAIT_OBJECT_0);

        // Get the exit code.
        bExitCodeProcess = GetExitCodeProcess(processInformation.hProcess, &rExitCode);

        // Close the handles.
        CloseHandle(processInformation.hProcess);
        CloseHandle(processInformation.hThread);

        if (!bExitCodeProcess)
        {
            // Could not get exit code.
            TRACE(_T("Executed command but couldn't get exit code.\nCommand=%s\n"), strCommand);
            return false;
        }

    //  if (rExitCode == 0) // We should have returned a value
        //  return false;

        return true;

    }

    return false;
}

调用代码执行此操作:

bool CGoogleAuthandSync::AddEventsToCalendarXML(CString strXML)
{
    CString strCommand = BuildCommandLine(_T("addtocalendarxml"), strXML);
    DWORD   dwExitCode;

    if (ExecuteProgram(strCommand, dwExitCode))
    {
        if (dwExitCode == 3)
            return true;
        else
        {
            CString strError;

            strError.Format(IDS_TPL_GOOGLE_UPDATE_FAILED, g_strResultDesc[dwExitCode]);
            AfxMessageBox(strError, MB_OK | MB_ICONINFORMATION);
            return false;
        }
    }

    return false;
}

最后,主要对话框(我的应用程序中的弹出窗口)执行保存机制,在运行外部实用程序之前将一些数据写入计算机:

bool bSyncToGoogle = false;
if (CGoogleCalendarSettingsDlg::GetSyncToGooglePrompt())
{
    if (AfxMessageBox(IDS_STR_SYNC_GOOGLE_CALENDAR_PROMPT, MB_YESNO | MB_ICONQUESTION) == IDYES)
        ExportToGoogleCalendar();
}
else if (CGoogleCalendarSettingsDlg::GetSyncToGoogle())
    ExportToGoogleCalendar();

SetModified(false);

因此,我的应用程序中有弹出编辑器(对话框)。

  • 用户点击保存
  • 它会创建一些数据文件。
  • 导出到Google日历。
  • 然后将修改后的标记设置为 false

现在,我认为我已经写过这样的方式,主窗口将等到我的实用程序完成后再继续。

但我发现一些用户可以点击保存,然后,真的很快,点击编辑器右上角的X.他们可以在 同步完成之前执行此操作。所以它认为它仍然被修改。

如果他们在点击右上角的X之前等待几秒钟,那么它会正确关闭,并认为该文档已不再修改。

所以我猜我有某种种族问题。但为什么?为什么我的应用程序在完成与Google的同步之前没有等待,并且在我允许用户甚至考虑关闭编辑器之前将其设置为false?

混淆。

1 个答案:

答案 0 :(得分:1)

这应该可以解决问题。将过程路径作为参数传递。

BOOL exeWait( char* file ) const
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    // Start the child process. 
    if( !CreateProcess( NULL,               // No module name (use command line). 
                    file,               // Command line. 
                    NULL,               // Process handle not inheritable. 
                    NULL,               // Thread handle not inheritable. 
                    FALSE,              // Set handle inheritance to FALSE. 
                    0,                  // No creation flags. 
                    NULL,               // Use parent's environment block. 
                    NULL,               // Use parent's starting directory. 
                    &si,                // Pointer to STARTUPINFO structure.
                    &pi )               // Pointer to PROCESS_INFORMATION structure.
                        ) 
    {
            return FALSE;
    }

    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess, INFINITE );

    // Close process and thread handles. 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

    return TRUE;
}