通过命令行参数创建进程来启动exe程序

在基于对话框的MFC项目的.cpp文件中,可以对函数InitInstance()修改来进行执行不同的命令行参数:

BOOL CMyDialogApp::InitInstance()
{
//TODO: call AfxInitRichEdit2() to initialize richedit2 library.
	// 如果一个运行在 Windows XP 上的应用程序清单指定要
	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
	//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// 将它设置为包括所有要在应用程序中使用的
	// 公共控件类。
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();


	AfxEnableControlContainer();

	AfxOleInit();
	AfxInitRichEdit2();

	// 创建 shell 管理器,以防对话框包含
	// 任何 shell 树视图控件或 shell 列表视图控件。
	CShellManager *pShellManager = new CShellManager;

	// 标准初始化
	// 如果未使用这些功能并希望减小
	// 最终可执行文件的大小,则应移除下列
	// 不需要的特定初始化例程
	// 更改用于存储设置的注册表项
	// TODO: 应适当修改该字符串,
	// 例如修改为公司或组织名
	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

	LPTSTR lpCmdLine = GetCommandLine();
	CStringArray saArgs;
	CmdLineToArr(lpCmdLine, saArgs);
	
	if (saArgs.GetSize() > 0 && saArgs.GetAt(0).CompareNoCase(_T("eeee")) == 0)
	{
		CMyDlg1 dlg(saArgs);
		m_pMainWnd = &dlg;
		INT_PTR nResponse = dlg.DoModal();
		if (nResponse == IDOK)
		{
			// TODO: 在此放置处理何时用
			//  “确定”来关闭对话框的代码
		}
		else if (nResponse == IDCANCEL)
		{
			// TODO: 在此放置处理何时用
			//  “取消”来关闭对话框的代码
		}
	}
	else
	{
		CMyDlg2 dlg(saArgs);
		m_pMainWnd = &dlg;
		INT_PTR nResponse = dlg.DoModal();
		if (nResponse == IDOK)
		{
			// TODO: 在此放置处理何时用
			//  “确定”来关闭对话框的代码
		}
		else if (nResponse == IDCANCEL)
		{
			// TODO: 在此放置处理何时用
			//  “取消”来关闭对话框的代码
		}
	}

	// 删除上面创建的 shell 管理器。
	if (pShellManager != NULL)
	{
		delete pShellManager;
	}

	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
	//  而不是启动应用程序的消息泵。
	return FALSE;
}

// 处理命令行参数并转化为数组进行存储
void CmdLineToArr(LPTSTR lpCmdLine, CStringArray& saArgv)
{
	CString strTemp, str;
	strTemp = lpCmdLine;
	strTemp.Trim();

	int nPos = strTemp.Find(_T(' '));
	while(nPos >= 0)
	{
		str = strTemp.Left(nPos+1);
		str.TrimRight();

		if(str.GetLength() > 0)
		{
			//如果参数的第一个字符是",那么向后找另一个",之间的是同一个参数
			if(str[0] == _T('"'))
			{
				int nPos1 = strTemp.Find(_T('"'), 1);
				if(nPos1 > 0)
				{
					nPos = nPos1;
					str = strTemp.Left(nPos);
					str = str.Mid(1);
				}
			}

			saArgv.Add(str);
		}

		strTemp = strTemp.Mid(nPos+1);
		nPos = strTemp.Find(_T(' '));
	}

	strTemp.Trim();
	if(strTemp.GetLength() > 0)
	{
		if( (strTemp[0] == _T('"')) && (strTemp[strTemp.GetLength() - 1] == _T('"')) )
			strTemp = strTemp.Mid(1, strTemp.GetLength()-2);

		saArgv.Add(strTemp);
	}

	if(saArgv.GetSize() == 0)
		return;
	
	CString sModelFileName;
	GetModuleFileName(AfxGetInstanceHandle(), sModelFileName.GetBuffer(MAX_PATH+1), MAX_PATH);
	sModelFileName.ReleaseBuffer();
	sModelFileName.Replace(_T('/'), _T('\\'));

	if((nPos = sModelFileName.ReverseFind(_T('\\'))) > 0)
		sModelFileName = sModelFileName.Mid(nPos + 1);

	if(sModelFileName.Right(4).CompareNoCase(_T(".exe")) == 0)
		sModelFileName = sModelFileName.Left(sModelFileName.GetLength() - 4);

	CString sFirst = saArgv[0];
	sFirst.Replace(_T('/'), _T('\\'));
	if((nPos = sFirst.ReverseFind(_T('\\'))) > 0)
		sFirst = sFirst.Mid(nPos + 1);

	if(sFirst.Right(4).CompareNoCase(_T(".exe")) == 0)
		sFirst = sFirst.Left(sFirst.GetLength() - 4);

	if(sFirst.CompareNoCase(sModelFileName) == 0)
		saArgv.RemoveAt(0);
}

{
// 通过命令行参数来启动程序
	CString sParam;
	sParam += _T("MyProgram.exe ggg fff");// argv[1]是 ggg , argv[2]是 fff

	STARTUPINFO startInfo;
	PROCESS_INFORMATION pinfo = { 0 };
	ZeroMemory(&startInfo, sizeof(startInfo));
	startInfo.cb = sizeof(startInfo);
	ZeroMemory(&pinfo, sizeof(pinfo));
	startInfo.dwFlags = STARTF_USESHOWWINDOW;
	startInfo.wShowWindow = SW_SHOW;

	BOOL bRet = ::CreateProcess(nullptr, sParam.GetBuffer(0), NULL, NULL, FALSE, 0, NULL, NULL, &startInfo, &pinfo);
	sParam.ReleaseBuffer();

	if (!bRet)
	{
		CHCString strFailure = _T("启动控制台程序失败:");
		strFailure += sParam;
		AfxMessageBox(strFailure);
		return false;
	}

	CloseHandle(pinfo.hProcess);
	CloseHandle(pinfo.hThread);
	}
{
// 调用exe
	CString sPath = _T("C:\\\\Model\\Data");
	//把任务目录当命令行参数传给.exe
	STARTUPINFO StartInfo; 
	PROCESS_INFORMATION pinfo = {0}; 
	memset(&StartInfo,0,sizeof(STARTUPINFO)); 
	StartInfo.cb = sizeof(STARTUPINFO);//设定结构的大小
	StartInfo.dwFlags = STARTF_USESHOWWINDOW;
	StartInfo.wShowWindow = SW_SHOW;

	LPTSTR lpStr =  (LPTSTR)(LPCTSTR)sPath;

	// 启动exe程序
	CString sModelFileName;
	GetModuleFileName(AfxGetInstanceHandle(), 	sModelFileName.GetBuffer(MAX_PATH+1), MAX_PATH);
	sModelFileName.ReleaseBuffer();
	sModelFileName.Replace(_T('/'), _T('\\'));
	int nPos = -1;
	if((nPos = sModelFileName.ReverseFind(_T('\\'))) > 0)
	{
		sModelFileName = sModelFileName.Left(nPos);
	}

	nPos = -1;
	if((nPos = sModelFileName.ReverseFind(_T('\\'))) > 0)
	{
		sModelFileName = sModelFileName.Left(nPos + 1);
	}
	CString sExePath = sModelFileName + _T("Tools\\mydata.exe");

	CreateBuildingsMapFile();

	BOOL bRet = CreateProcess(sExePath, lpStr, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartInfo, &pinfo);
	if(bRet == FALSE)
	{
		DWORD dwErr = GetLastError();
		CString sMsg;
		sMsg.Format(_T("启动服务程序 %s 失败,错误码%d(0x%X)"), (LPCTSTR)sExePath, dwErr, dwErr);
		AfxMessageBox(sMsg);

		return;
	}
	else
	{
		CloseHandle(pinfo.hProcess);
		CloseHandle(pinfo.hThread);
	}
}

你可能感兴趣的:(MFC,多线程多进程,CreateProcess)