上周,老师布置了作业,用c++控制程序,自己在网上搜了一些,实现了一次简单的功能,和大家共享一下。
WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件。
1.1函数原型
BOOL CreateProcess (
LPCTSTRlpApp licationName, //指定可执行模块的地址,如果为空,则必须在下一个参数中指定运行的可执行程序LPTSTR lpCommandLine, //执行的命令行,如果为空,函数将使用lpApplicationName参数指定的字符串当做要运行的程序的命令行LPSECURITY_ATTRIBUTES lpProcessAttributes。 //指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。如果l // pProcessAttributes参数为空(NULL),那么句柄不能被继承。LPSECURITY_ATTRIBUTES lpThreadAttributes, //指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的指向线程的句柄可以被子进程继 //承。如果lpThreadAttributes参数为空(NULL),那么句柄不能被继承。BOOL bInheritHandles, //指示新进程是否从调用进程处继承了句柄。DWORD dwCreationFlags, //指定附加的、用来控制优先类和进程的创建的标志LPVOID lpEnvironment, //指向一个新进程的环境块。如果此参数为空,新进程使用调用进程的环境。LPCTSTR lpCurrentDirectory, //指定定子进程的工作路径。这个字符串必须是一个包含驱动器名的绝对路径。如果这个参数为空,新 //进程将使用与调用进程相同的驱动器和目录。LPSTARTUPINFO lpStartupInfo, //指向一个用于决定新进程的主窗体如何显示的STARTUPINFO结构体。LPPROCESS_INFORMATION lpProcessInformation //指向一个用来接收新进程的识别信息的PROCESS_INFORMATION结构体。
);
以上参考百度百科http://baike.baidu.com/view/697167.htm
1.2.重要参数详解
1.2.1 LPSTARTUPINFO
typedefstruct _STARTUPINFO { DWORD cb; //包含STARTUPINFO结构中的字节数.如果Microsoft将来扩展该结构,它可用作版本控制手段.应用程序必须将cb初始化为sizeof ( STARTUPINFO ) PSTR lpReserved; //保留。必须初始化为N U L L PSTR lpDesktop; //用于标识启动应用程序所在的桌面的名字。如果该桌面存在,新进程便与指定的桌面相关联。如果桌面不存在,便创建一个带有默认属性的桌面,并使用为新进程指定的名字。 如果lpDesktop是NULL(这是最常见的情况 ),那么该进程将与当前桌面相关联 PSTR lpTitle; //用于设定控制台窗口的名称。如果l p Ti t l e 是N U L L ,则可执行文件的名字将用作窗口名 DWORD dwX; //用于设定应用程序窗口在屏幕上应该放置的位置的x 和y 坐标(以像素为单位)。 DWORD dwY; //只有当子进程用CW_USEDEFAULT作为CreateWindow的x参数来创建它的第一个重叠窗口时, 才使用这两个坐标。若是创建控制台窗口的应用程序,这些成员用于指明控制台窗口的左上角 DWORD dwXSize; //用于设定应用程序窗口的宽度和长度(以像素为单位)只有dwYsize DWORD dwYSize; // 当子进程将CW_USEDEFAULT 用作CreateWindow 的nWidth参数来创建它的第一个重叠窗口时,才使用这些值。若是创建控制台窗口的应用程序,这些成员将用于指明控制台窗口的宽度 DWORD dwXCountChars; //用于设定子应用程序的控制台窗口的宽度和高度(以字符为单位) DWORD dwYCountChars; DWORD dwFillAttribute; //用于设定子应用程序的控制台窗口使用的文本和背景颜色 DWORD dwFlags; //请参见下一段和表4 - 7 的说明 WORD wShowWindow; //用于设定如果子应用程序初次调用的ShowWindow 将SW_SHOWDEFAULT 作为 nCmdShow 参数传递时,该应用程序的第一个重叠窗口应该如何出现。本成员可以是通常用于ShowWindow 函数的任何一个SW_*标识符 WORD cbReserved2; //保留。必须被初始化为0 PBYTE lpReserved2; //保留。必须被初始化为N U L L HANDLE hStdInput; //用于设定供控制台输入和输出用的缓存的句柄。按照默认设置,hStdInput 用于标识键盘缓存,hStdOutput 和hStdError用于标识控制台窗口的缓存 HANDLE hStdOutput; HANDLE hStdError; } STARTUPINFO, *LPSTARTUPINFO;
以上参考自http://blog.csdn.net/akof1314/article/details/5471727,具体的详细介绍。
1.2.PROCESS_INFORMATION
typedefstruct _PROCESS_INFORMATION { HANDLE hProcess; //存放每个对象的与进程相关的句柄 HANDLE hThread; //返回的线程句柄。 DWORD dwProcessId; //用来存放进程ID号 DWORD dwThreadId; //用来存放线程ID号 } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
以参考自http://hi.baidu.com/netcicala/blog/item/6bff1c2e646abb554fc226e2.html
以下是在win32下编译运行,用的是VS2010.
#include<Windows.h> //#include<stdio.h> #include<iostream> #include <Psapi.h> #include <string> #include <Tlhelp32.h> using namespace std; bool KillProcess(DWORD dwPid) { HANDLE hPrc; if( 0 == dwPid) return FALSE; hPrc = OpenProcess( PROCESS_ALL_ACCESS, NULL, dwPid); // Opens handle to the process. if( !TerminateProcess(hPrc,0) ) // Terminates a process. { CloseHandle( hPrc ); cout<<"error"<<endl; return FALSE; } else WaitForSingleObject(hPrc, 2000); // At most ,waite 2000 millisecond. CloseHandle(hPrc); return TRUE; } bool KillProcessByName(const TCHAR *lpszProcessName) { unsigned int pid = -1; BOOL retval = TRUE; if (lpszProcessName == NULL) return -1; DWORD dwRet = 0; HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS,0 ); PROCESSENTRY32 processInfo; processInfo.dwSize = sizeof( PROCESSENTRY32 ); int flag = Process32First( hSnapshot, &processInfo ); // Find the process with name as same as lpszProcessName while (flag != 0) { if (strcmp(processInfo.szExeFile, lpszProcessName) == 0) { // Terminate the process. pid = processInfo.th32ProcessID; HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid); if (TerminateProcess(hProcess, 0) != TRUE) { // Failed to terminate it. retval = FALSE; break; } } flag = Process32Next(hSnapshot, &processInfo); } // while (flag != 0) CloseHandle(hSnapshot); if (pid == -1) return FALSE; return retval; } int main(int arg,char *argv[]) { //创建进程 //进程路径 char commandLine[] = "C:\\\\Program Files\\\\Internet Explorer\\\\iexplore.exe"; STARTUPINFO startInfo = { sizeof(startInfo)}; PROCESS_INFORMATION procInfo; startInfo.dwFlags = STARTF_USESHOWWINDOW; //显示窗口 startInfo.wShowWindow = TRUE;//显示窗口 BOOL bRet=::CreateProcessA ( NULL, commandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startInfo, &procInfo); //关闭进程 //进程句柄 if(bRet) { ::CloseHandle (procInfo.hThread); ::CloseHandle (procInfo.hProcess); printf(" 新进程的进程Id号: %d \n",procInfo.dwProcessId); printf(" 新进程的主线程ID号: %d \n",procInfo.dwThreadId); } Sleep(2000); if(KillProcess(procInfo.dwThreadId)) { cout<<"success"<<endl; } KillProcessByName(" QQ.exe"); HANDLE processHandle; //进程ID ULONG processID; //进程窗口句柄 HWND theWindow; //FindWindow theWindow = ::FindWindow( NULL,"ie"); ::GetWindowThreadProcessId( theWindow,&processID ); processHandle = ::OpenProcess( PROCESS_TERMINATE,FALSE,processID ); ::TerminateProcess( processHandle,4); return 0; }
以上关闭进程还未实现,未完待续,大家有好的建议可以提出来