项目里有几个应用程序,它们之间有先后关系,有时需要在某个程序中,重新启动另外一个应用程序,因此需要找到windows api来实现。
在这里列举三种情况:在程序中,纯粹打开外部应用程序、纯粹关闭外部应用程序、打开应用程序后过会儿再关闭它。
我在这里只讲方法,不讲原理(因为windows api 太恶心了)
1,纯粹打开外部应用程序:使用ShellExecute()
#include<iostream>
#include<Windows.h>
#include<shellapi.h>
int main(int argc, char* argv[])
{
ShellExecute(0,L"open",L"e:/GWSLN/gwsln/Debug/Collector.exe",L"",L"",SW_SHOWNORMAL);
……
}
它的第三个参数为我们要打开的应用程序。
注意点:
windows api 使用自身的数据类型,因此想要传递字符串时,在字符串前加上 L 。
2,纯粹关闭外部应用程序:使用FindWindow()找到应用程序窗口句柄,用GetWindowThreadProcessId() 得到该句柄对应的进程ID,然后关闭该进程。
#include<iostream>
#include<Windows.h>
#include<shellapi.h>
int main(int argc, char* argv[])
{
HANDLE hProcessHandle;
ULONG nProcessID;
HWND TheWindow;
TheWindow = ::FindWindow( NULL, L"计算器");//找到键盘窗口句柄
//"VVr2Keyboard"为键盘程序的名称
if(NULL == TheWindow){
return FALSE;
}
::GetWindowThreadProcessId( TheWindow, &nProcessID );
hProcessHandle =::OpenProcess( PROCESS_TERMINATE,FALSE, nProcessID );
::TerminateProcess( hProcessHandle, 4 );
……
}
注意点:
上面的FindWindow() 的第二个参数,是windows应用程序窗口左上方的那些东东,必须完全一致才能够打开,而不是应用程序在硬盘的存储位置。如我打开了计算器了,想要在应用程序里面关闭它,它的第二个参数就是窗口栏上的名称。如图:
3,打开应用程序后过会儿再关闭它。使用ShellExecuteEx() 和 TerminateProcess() 来实现。
#include<iostream>
#include<Windows.h>
#include<shellapi.h>
int main(int argc, char* argv[])
{
SHELLEXECUTEINFO e1;
memset(&e1,0,sizeof(e1));
e1.cbSize=sizeof(e1);
e1.hwnd=NULL;
e1.lpFile=L"e:/GWSLN/gwsln/Debug/Collector.exe";
e1.nShow=1;
e1.fMask=SEE_MASK_NOCLOSEPROCESS;
ShellExecuteEx(&e1);
Sleep(5000);
TerminateProcess(e1.hProcess,0);
}
通过填充一个 SHELLEXECUTEINFO 结构体,用它作为ShellExecuteEx()的参数,来打开应用程序,此函数跟ShellExecute() 函数的区别是,ShellExecute()在打开应用程序后,就关闭了该应用程序的句柄,就此两个应用程序不再产生关联。而ShellExecuteEx()打开应用程序后,把该应用程序的句柄保存在结构体的 .hProcess里面,以后可以通过该句柄关闭外部应用程序。