这是我在 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);
因此,我的应用程序中有弹出编辑器(对话框)。
现在,我认为我已经写过这样的方式,主窗口将等到我的实用程序完成后再继续。
但我发现一些用户可以点击保存,然后,真的很快,点击编辑器右上角的X.他们可以在 同步完成之前执行此操作。所以它认为它仍然被修改。
如果他们在点击右上角的X之前等待几秒钟,那么它会正确关闭,并认为该文档已不再修改。
所以我猜我有某种种族问题。但为什么?为什么我的应用程序在完成与Google的同步之前没有等待,并且在我允许用户甚至考虑关闭编辑器之前将其设置为false?
混淆。
答案 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;
}