項目裏有幾個應用程序,它們之間有先後關係,有時需要在某個程序中,重新啓動另外一個應用程序,因此需要找到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裏面,以後可以通過該句柄關閉外部應用程序。