在编程过程中有个需求,点击某个按钮需要弹出系统的声音控制面板。在网上查了下代码中调用其他exe程序或者打开其他文件的方法。
自己借鉴网上的文章稍微总结下,加深下印象,也给方便自己用。
在代码中调用其他exe程序或者打开其他功能末班的方法主要有以下几种:
1.使用system函数
system函数,函数原型system(执行shell命令)定义函数是,int system(const char * string),可以调用一些DOS命令,比如:
system("cls");//清屏,等于在DOS上使用cls命令
例如:system("pause");//暂停当前的进程
system("dir"); //列出当前项目文件的目录
system函数会调用fork()函数产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回调用的进程,system函数不能控制程序窗口是否显示。一般在项目中,这种方法不予考虑。
2.使用execl或execv函数
这是exec函数族里面的两个函数,在UNIX环境下用的比较多,exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,也就是说在调用进程内部执行一个可执行文件,这里的可执行文件既可以是二进制文件,也可以是任何Linux下的可执行的脚本文件,与一般情况不同,exec函数族的函数执行成功后不会返回,只有调用失败了才会返回一个-1,从原程序的调用点接着往下执行。它也是不能控制程序窗口是否显示。
3.WinExec函数
WinExec函数可以方便地在应用程序中执行一个程序,执行一个标准程序一般使用:
WinExec(\'C:\WINDOWS\NOTEPAD.EXE\', SW_SHOWNORMAL);
第二个参数是控制程序主窗口的显示方式,用WinExec只能执行exe文件,但是WinExec函数不好控制主程序来等该exe程序的结束。WinExec是Windows的老函数了,现在的CreateProcess几乎可以替代WinExe的所有功能。
4.ShellExcecuteEx函数
这个函数主要是在文件上执行一个函数,如果执行成功则返回一个非0值,否则返回一个0值。函数的原型是:
WINSHELLAPI BOOL WINAPI ShellExecuteEx(
LPSHELLEXECUTEINFO lpExecInfo);
参数lpExecInfo:是数据结构 LPSHELLEXECUTEINFO 的地址,包含了和接收一些被执行的应用程序的一些信息。下面是一个使用的示例:
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = _T("open");
ShExecInfo.lpFile = _T("a.exe");
ShExecInfo.lpParameters = _T("-a a");
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_HIDE;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
AfxGetApp()->BeginWaitCursor();
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
AfxGetApp()->EndWaitCursor();
这个函数可以通过ShExecInfo.lpParameters来传递exe文件的参数,通过属性ShExecInfo.nShow来控制程序窗口是否显示。
后面三个函数都是SDK函数,现在在执行项目中的exe文件的时候,使用比较多的就是后面得两个函数,我在自己的项目中使用的就是ShellExecuteEx函数,比CreateProcess函数使用方便一些。
5.使用CreateProcess函数
CreateProcess函数是新建一个进程,下面是一个使用CreateProcess函数的例子:
void createchildprocessandwaituntildone(const ansistring& strcmdline)
{
process_information piprocinfo;
startupinfo sistartinfo;
// set up members of startupinfo structure.
sistartinfo.cb = sizeof(startupinfo);
sistartinfo.lpreserved = null;
sistartinfo.lpreserved2 = null;
sistartinfo.cbreserved2 = 0;
sistartinfo.lpdesktop = null;
sistartinfo.dwflags = 0;
// create the child process.
createprocess(
null,
strcmdline.c_str(),
null, // process security attributes
null, // primary thread security attributes
0, // handles are inherited
0, // creation flags
null, // use parent\\'s environment
null, // use parent\\'s current directory
&sistartinfo, // startupinfo pointer
&piprocinfo); // receives process_information
// wait for the processs to finish
dword rc = waitforsingleobject(
piprocinfo.hprocess, // process handle
infinite);
}
使用CreateProcess函数,你必须人为地控制该进程的生死,这一方面是使用进程控制来实现。进程控制的意义在于可以创建一个进程,并且可以通过进程句柄结束进程。
VC中调用其他可执行程序,就我目前所知有三种方法:
HINSTANCE ShellExecute(HWND hwnd, LPCTSTRlpVerb,LPCTSTRlpFile,LPCTSTRlpParameters,LPCTSTRlpDirectory,INTnShowCmd);
特殊需要讲的参数:
lpVerb:对lpFile要执行的行为,包括"open","explore","print","edit","find","properties"
lpFile:要操作的对象
lpParameters:传递给为lpFile的参数
nShowCmd:窗口的显示参数,不显示(SW_HIDE)
注意:返回值如果小于32,则是错误,见具体错误
其扩展函数ShellExecuteEx功能更全
此函数声明包含在头文件shellapi.h,库是shell32.lib- UINT WinExec(
LPCSTR lpCmdLine, // command line
UINT uCmdShow // window style
);
参数lpCmdLine为文件名+参数
如果执行正确,返回值大于31
声明在头文件windows.h,包含在kernel32.lib中 - BOOL CreateProcess(
LPCTSTR lpApplicationName, // name of executable module
LPTSTR lpCommandLine, // command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
BOOL bInheritHandles, // handle inheritance option
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // new environment block
LPCTSTR lpCurrentDirectory, // current directory name
LPSTARTUPINFO lpStartupInfo,// startup information
LPPROCESS_INFORMATION lpProcessInformation // process information
);
这个够复杂,启动一个进程的方式打开一个程序。声明所在的头文件和库同WinExec
以上三种方法,推荐使用第一种。第二种不推荐使用,因为它存在只是为了支持16位机的。
还需要考虑另外一个问题,就是后面程序的执行,可能需要等待这个进程结束之后才能执行,而不能两个进程并发执行。(两个进程一个是原进程,一个是启动的进程)。参考了:http://www.cnblogs.com/del/archive/2008/02/13/1067871.html
可以如下使用:
HANDLE hProg;
hProg=ShellExecute(NULL, "open", "xxx.exe", NULL, NULL, SW_HIDE);
WaitForSingleObject(hProg, INIFINTE);
在我使用的时候是要用一个MFC程序打开一个控制台程序,控制台程序执行结果写入到一个文档中,然后再用mfc程序读出。(为什么这么麻烦,是因为控制台程序用到的库是第三方库,不支持MFC,没办法)。
在控制台程序结束时,写的文件未必已经写完,并关闭了。所以还需要额外做些工作。
While(!FileExists(Result.TXT)) ;
READFile(Result.TXT);
注意while语句后面的";"
ShellExecute:
1.函数功能:
你可以给它任何文件的名字,它都能识别出来并打开它。
2.函数原型:
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
3.参数说明:
hwnd:
用于指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。
lpOperation:
用于指定要进行的操作。
“open”操作表示执行由lpFile参数指定的程序,或打开由lpFile参数指定的文件或文件夹;
“print”操作表示打印由lpFile参数指定的文件;
“explore”操作表示浏览由lpFile参数指定的文件夹。
当参数设为NULL时,表示执行默认操作“open”。
lpFile:
用于指定要打开的文件名、要执行的程序文件名或要浏览的文件夹名。
lpParameters:
若lpFile参数是一个可执行程序,则此参数指定命令行参数,否则此参数应为NULL.
lpDirectory:
用于指定默认目录.
nShowCmd:
若lpFile参数是一个可执行程序,则此参数指定程序窗口的初始显示方式,否则此参数应设置为0。
这个参数常用的常数:
SW_HIDE 隐藏窗口,活动状态给令一个窗口
SW_MINIMIZE 最小化窗口,活动状态给令一个窗口
SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOWMAXIMIZED 最大化窗口,并将其激活
SW_SHOWMINIMIZED 最小化窗口,并将其激活
SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口
SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口
SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口
SW_SHOWNORMAL 与SW_RESTORE相同
若ShellExecute函数调用成功,则返回值为被执行程序的实例句柄。若返回值小于32,则表示出现错误。
4.使用方法:
例如:
ShellExecute(NULL,"open","iloveu.bmp",NULL,NULL,SW_SHOWNORMAL);
用缺省的位图编辑器打开一个叫iloveu.bmp的位图文件,这个缺省的位图编辑器可能是 Microsoft Paint, Adobe Photoshop, 或者 Corel PhotoPaint。
这个函数能打开任何文件,甚至是桌面和URL快捷方式( .ink或 .url)。ShellExecute解析系统注册表HKEY_CLASSES_ROOT中所有的内容,判断启动那一个执行程序,并且启动一个新的实例或使用DDE将文件名连到一打开的实例。然后,ShellExecute 返回打开文件的应用的实例句柄。
ShellExecute(NULL, "open", "http://www.microsoft.com", NULL, NULL, SW_SHOWNORMAL);
这个代码使你能访问微软的主页。当ShellExecute遇到文件名前面的“http:”时,可以判断出要打开的文件是Web文件,随之启动Internet Explorer 或者 Netscape Navigator 或者任何你使用的别的浏览器打开文件。
ShellExecute还能识别其它协议,象FTP、GOPHER。甚至识别“mailto”,如果文件名指向“mailto:zxn@hq.cninfo.net”,它启动电子邮件程序并打开一个待编辑的新邮件,例如:
ShellExecute(NULL, "open",“mailto:zxn@hq.cninfo.net”, NULL, NULL, SW_SHOWNORMAL);打开新邮件窗口。
总之,ShellExecute函数就是如此简单地打开磁盘文件和Internet文件。如果将第二个参数“OPEN”改为“PRINT”或者“EXPLORE”,ShellExecute将能打印文件和打开文件夹。ShellExecute还有一个扩展函数ShellExecuteEx,所带参数中有一个特殊的结构,功能更强,或者任何你使用的别的浏览器打开文件。
======================================================================================
VC中调用其他可执行程序,就我目前所知有三种方法:
HINSTANCE ShellExecute(HWND hwnd, LPCTSTRlpVerb,LPCTSTRlpFile,LPCTSTRlpParameters,LPCTSTRlpDirectory,INTnShowCmd);
特殊需要讲的参数:
lpVerb:对lpFile要执行的行为,包括"open","explore","print","edit","find","properties"
lpFile:要操作的对象
lpParameters:传递给为lpFile的参数
nShowCmd:窗口的显示参数,不显示(SW_HIDE)
注意:返回值如果小于32,则是错误,见具体错误
其扩展函数ShellExecuteEx功能更全
此函数声明包含在头文件shellapi.h,库是shell32.lib- UINT WinExec(
LPCSTR lpCmdLine, // command line
UINT uCmdShow // window style
);
参数lpCmdLine为文件名+参数
如果执行正确,返回值大于31
声明在头文件windows.h,包含在kernel32.lib中 - BOOL CreateProcess(
LPCTSTR lpApplicationName, // name of executable module
LPTSTR lpCommandLine, // command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
BOOL bInheritHandles, // handle inheritance option
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // new environment block
LPCTSTR lpCurrentDirectory, // current directory name
LPSTARTUPINFO lpStartupInfo,// startup information
LPPROCESS_INFORMATION lpProcessInformation // process information
);
这个够复杂,启动一个进程的方式打开一个程序。声明所在的头文件和库同WinExec
以上三种方法,推荐使用第一种。第二种不推荐使用,因为它存在只是为了支持16位机的。
还需要考虑另外一个问题,就是后面程序的执行,可能需要等待这个进程结束之后才能执行,而不能两个进程并发执行。(两个进程一个是原进程,一个是启动的进程)。参考了:http://www.cnblogs.com/del/archive/2008/02/13/1067871.html
可以如下使用:
HANDLE hProg;
hProg=ShellExecute(NULL, "open", "xxx.exe", NULL, NULL, SW_HIDE);
WaitForSingleObject(hProg, INIFINTE);
在我使用的时候是要用一个MFC程序打开一个控制台程序,控制台程序执行结果写入到一个文档中,然后再用mfc程序读出。(为什么这么麻烦,是因为控制台程序用到的库是第三方库,不支持MFC,没办法)。
在控制台程序结束时,写的文件未必已经写完,并关闭了。所以还需要额外做些工作。
While(!FileExists(Result.TXT)) ;
READFile(Result.TXT);
注意while语句后面的";"
ShellExecute:
1.函数功能:
你可以给它任何文件的名字,它都能识别出来并打开它。
2.函数原型:
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
3.参数说明:
hwnd:
用于指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。
lpOperation:
用于指定要进行的操作。
“open”操作表示执行由lpFile参数指定的程序,或打开由lpFile参数指定的文件或文件夹;
“print”操作表示打印由lpFile参数指定的文件;
“explore”操作表示浏览由lpFile参数指定的文件夹。
当参数设为NULL时,表示执行默认操作“open”。
lpFile:
用于指定要打开的文件名、要执行的程序文件名或要浏览的文件夹名。
lpParameters:
若lpFile参数是一个可执行程序,则此参数指定命令行参数,否则此参数应为NULL.
lpDirectory:
用于指定默认目录.
nShowCmd:
若lpFile参数是一个可执行程序,则此参数指定程序窗口的初始显示方式,否则此参数应设置为0。
这个参数常用的常数:
SW_HIDE 隐藏窗口,活动状态给令一个窗口
SW_MINIMIZE 最小化窗口,活动状态给令一个窗口
SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOWMAXIMIZED 最大化窗口,并将其激活
SW_SHOWMINIMIZED 最小化窗口,并将其激活
SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口
SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口
SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口
SW_SHOWNORMAL 与SW_RESTORE相同
若ShellExecute函数调用成功,则返回值为被执行程序的实例句柄。若返回值小于32,则表示出现错误。
4.使用方法:
例如:
ShellExecute(NULL,"open","iloveu.bmp",NULL,NULL,SW_SHOWNORMAL);
用缺省的位图编辑器打开一个叫iloveu.bmp的位图文件,这个缺省的位图编辑器可能是 Microsoft Paint, Adobe Photoshop, 或者 Corel PhotoPaint。
这个函数能打开任何文件,甚至是桌面和URL快捷方式( .ink或 .url)。ShellExecute解析系统注册表HKEY_CLASSES_ROOT中所有的内容,判断启动那一个执行程序,并且启动一个新的实例或使用DDE将文件名连到一打开的实例。然后,ShellExecute 返回打开文件的应用的实例句柄。
ShellExecute(NULL, "open", "http://www.microsoft.com", NULL, NULL, SW_SHOWNORMAL);
这个代码使你能访问微软的主页。当ShellExecute遇到文件名前面的“http:”时,可以判断出要打开的文件是Web文件,随之启动Internet Explorer 或者 Netscape Navigator 或者任何你使用的别的浏览器打开文件。
ShellExecute还能识别其它协议,象FTP、GOPHER。甚至识别“mailto”,如果文件名指向“mailto:zxn@hq.cninfo.net”,它启动电子邮件程序并打开一个待编辑的新邮件,例如:
ShellExecute(NULL, "open",“mailto:zxn@hq.cninfo.net”, NULL, NULL, SW_SHOWNORMAL);打开新邮件窗口。
总之,ShellExecute函数就是如此简单地打开磁盘文件和Internet文件。如果将第二个参数“OPEN”改为“PRINT”或者“EXPLORE”,ShellExecute将能打印文件和打开文件夹。ShellExecute还有一个扩展函数ShellExecuteEx,所带参数中有一个特殊的结构,功能更强,或者任何你使用的别的浏览器打开文件。
======================================================================================
Q: 如何打开一个应用程序
ShellExecute(this->m_hWnd,"open","calc.exe","","", SW_SHOW ); 或 ShellExecute(this->m_hWnd,"open","notepad.exe","c:\\MyLog.log","",SW_SHOW ); 正如您所看到的,我并没有传递程序的完整路径。
Q: 如何打开一个同系统程序相关连的文档?ShellExecute(this->m_hWnd,"open","c:\\abc.txt","","",SW_SHOW );
Q: 如何打开一个网页?
ShellExecute(this->m_hWnd,"open","http://www.google.com","","", SW_SHOW );
Q: 如何激活相关程序,发送EMAIL?
ShellExecute(this->m_hWnd,"open","mailto:nishinapp@yahoo.com","","", SW_SHOW );
Q: 如何用系统打印机打印文档?
ShellExecute(this->m_hWnd,"print","c:\\abc.txt","","", SW_HIDE);
Q: 如何用系统查找功能来查找指定文件?
ShellExecute(m_hWnd,"find","d:\\nish",NULL,NULL,SW_SHOW);
Q: 如何启动一个程序,直到它运行结束?
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "c:\\MyProgram.exe";
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
或:
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
if(CreateProcess("c:\\winnt\\notepad.exe", NULL,
NULL,NULL,FALSE,0,NULL,
NULL,&StartupInfo,&ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
}
else
{
MessageBox("The process could not be started...");
}
Q: 如何显示文件或文件夹的属性?
SHELLEXECUTEINFO ShExecInfo ={0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "properties";
ShExecInfo.lpFile = "c:\\"; //can be a file as well
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);