(分享)同步或异步调用EXE(创建子进程并重定向子进程的输入、输出)

BeanJoy 2014-06-11 02:08:22
  分享个自己写的创建子进程并重定向子进程的输入、输出的类,使用时最少只调用一个接口就行了。调用时可以设置超时时长,可以以同步或异步方式调用,可以取消调用。写这个类主要是因为后面的工作会调用一些EXE完成一些操作。目的是分享哈,方便有相同需求的网友,不是教学之类的,用到的技术也不是新技术哈。
  博文:同步或异步调用EXE(创建子进程并重定向子进程的输入、输出)
  下载地址:同步或异步调用EXE(创建子进程并重定向子进程的输入、输出)
  还是把代码也帖上:
  InvokeExternalExe.h
// InvokeExternalExe.h: interface for the CInvokeExternalExe class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_INVOKEEXTERNALEXE_H__9BA72D3F_E9AD_4054_9F51_7C5281B2D2F2__INCLUDED_)
#define AFX_INVOKEEXTERNALEXE_H__9BA72D3F_E9AD_4054_9F51_7C5281B2D2F2__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <Windows.h>
#include <string>
#include <tchar.h>

#if (defined UNICODE) || (defined _UNICODE)
#define tstring std::wstring
#else
#define tstring std::string
#endif

// 调用的程序中途输出信息后,会调用此回调
// pUserData : CInvokeExternalExe::SetUserData()设置的值
// pButOutput : 调用的程序输出信息的Buffer,可能存的是ANSI,也可能存的是UNICODE
// dwOutputSize : 调用的程序输出信息Buffer大小
typedef BOOL (__stdcall * LPExecuteOutputCB)(
const void * const pUserData,
const CHAR * const pButOutput,
DWORD dwOutputSize
);

// 异步调用时,执行完程序得到结果后会回调
// pUserData : CInvokeExternalExe::SetUserData()设置的值
// bInvodeSuccess : 调用是否成功
// dwExitCode : 若调用成功,保存应用程序的退出代码
// strErrorMsg : 若调用失败,返回失败信息
typedef BOOL (__stdcall * LPAsyncInvokeResultCB)(
const void * const pUserData,
const BOOL bInvodeSuccess,
const DWORD dwExitCode,
const tstring strErrorMsg
);

class CAutoLock
{
private:
LPCRITICAL_SECTION m_pcsLcok;

public:
CAutoLock(LPCRITICAL_SECTION pcsLcok)
{
m_pcsLcok = pcsLcok;
if (m_pcsLcok)
{
EnterCriticalSection(m_pcsLcok);
}
}

~CAutoLock()
{
if (m_pcsLcok)
{
LeaveCriticalSection(m_pcsLcok);
m_pcsLcok = NULL;
}
}
};

class CInvokeExternalExe
{
private:
void *m_pUserData;
LPExecuteOutputCB m_pExecuteOutputCB;
LPAsyncInvokeResultCB m_pAyncInvokeResultCB;
HANDLE m_hChildStd_IN_Rd;
HANDLE m_hChildStd_IN_Wr;
HANDLE m_hChildStd_OUT_Rd;
HANDLE m_hChildStd_OUT_Wr;
HANDLE m_hProcessHandle;
HANDLE m_hOutputThreadHandle;
BOOL m_bInvokeFinish;
HANDLE m_hAsyncInvokeThreadHandle;
BOOL m_bIsInvoking;

// 异步调用时需要保存以下信息
BOOL m_bApplicationNameIsNull;
tstring m_strApplicationName;
BOOL m_bCommandLineIsNull;
tstring m_strCommandLine;
DWORD m_dwMilliseconds;
WORD m_wShowWindow;

CRITICAL_SECTION m_csLock;

private:
tstring GetLastErrorMsg(LPCTSTR lpszFunction, const DWORD dwLastError);
void CloseAllHandles();

unsigned ReadOutput();
static unsigned __stdcall ReadOutputThreadFunc(void* pArguments);

unsigned AsyncInvoke();
static unsigned __stdcall AsyncInvokeThreadFunc(void* pArguments);

// 同步调用
BOOL Invoke(
IN LPCTSTR lpApplicationName,
IN LPTSTR lpCommandLine,
IN const DWORD dwMilliseconds,
IN const WORD wShowWindow,
OUT DWORD &dwExitCode,
OUT tstring &strErrorMsg
);

public:
CInvokeExternalExe();
virtual ~CInvokeExternalExe();

public:
void SetUserData(void *pUserData)
{
m_pUserData = pUserData;
}

void SetExecuteOutputCB(LPExecuteOutputCB pExecuteOutputCB)
{
m_pExecuteOutputCB = pExecuteOutputCB;
}

void SetAsyncInvokeResultCB(LPAsyncInvokeResultCB pAsyncInvokeResultCB)
{
m_pAyncInvokeResultCB = pAsyncInvokeResultCB;
}

// 同步调用时返回值表示调用应用程序是否成功
// 异常调用表示发起调用是否成功
BOOL Invoke(
IN LPCTSTR lpApplicationName, // 应用程序名
IN LPTSTR lpCommandLine, // 参数
IN const BOOL bSynchronousInvoke, // 是否同步调用
IN const DWORD dwMilliseconds, // 超时时长,单位毫秒,0表示不超时
IN const WORD wShowWindow, // 是否显示窗口,可传SW_...系列的宏
OUT DWORD &dwExitCode, // 调用成功后,应用程序的退出代码
OUT tstring &strErrorMsg // 若调用失败,返回失败信息
);

// 取消调用
void CancelInvoke();
};

#endif // !defined(AFX_INVOKEEXTERNALEXE_H__9BA72D3F_E9AD_4054_9F51_7C5281B2D2F2__INCLUDED_)


  源代码帖不上了,下载或到博文件去看吧。
...全文
255 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
BeanJoy 2014-06-11
  • 打赏
  • 举报
回复
引用 2 楼 dingxz105090 的回复:
为什么命令行是“ping www.baidu.com -t”等调用Cmd的时候,应用程序名必须为空?写了反而无效呢
应用程序名和命令行,是CreateProcess定义的,可以看看MSDN上对CreateProcess前两个参数的说明。 另外,cmd命令执行字符串,需要加上/c。因此,命令行应该写/c ping www.baidu.com -t。
凌乱哥 2014-06-11
  • 打赏
  • 举报
回复
为什么命令行是“ping www.baidu.com -t”等调用Cmd的时候,应用程序名必须为空?写了反而无效呢
凌乱哥 2014-06-11
  • 打赏
  • 举报
回复
先回再看,表示还没看懂有什么实际用途。。

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧