shellexecute
winexec
CreateProcess
void main( VOID )
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line).
"MyChildProcess", // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
ErrorExit( "CreateProcess failed." );
}
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
杀死一个进程
| 代码简介或代码解析: | |
| 本例的进程处理器程序实现了进程的列举、进程的切换、启动新的进程、杀死进程、命令行处理等功能。 一、进程的列举类CProcessList: 使用类CProcessList,我们能很方便列举当前系统中正在运行的进程。它不需要你另外考虑系统兼容的问题,因为所有这些事情它都已经做好了相应的处理。基于这些原因,你不能再象使用其他类那样仅仅初始化一个CProcessList的对象,你将必须先“Create()”: CProcessList * pProcessList = CProcessList::Create(); 然后得到进程快照: pProcessList->SnapShot(); 做完这项工作后,您就可以将所有进程通过列表重现出来: CProcess * pProcess; while((pProcess = pProcessList->GetNextProcess()) != 0) { TRACE("process' filename: \"%s\" PID: %lu\n", LPCTSTR(pProcess->GetFilename()), pProcess- >GetPID()); } 最后在恰当时候你必须删除它: delete pProcessList; 二、进程的管理类CProcessMgr: 该类成员函数ParseCommand分析命令行;Execute函数则执行命令;Wait函数等待其他进程;IsProgramRunning函数检查某程序是否在运行;SwitchProcessIntoForeground函数切换到某个正在运行的程序上;GetLinkInfo函数得到shell-link(快捷方式)的信息。OnExecError函数处理错误信息。 类CProcessMgr的一个主要目标是能够理解复杂的命令行字符串。比如如下BNF-notation: CmdLine : command | command arguments | 'cd' directory ';' command | 'cd' directory ';' command arguments command : string arguments: string | arguments string directory: string /* shall consist of a full path ! */ string : '[^ \t]+' /* string without blanks/tabs */ | '"' '[^"]*' '"' /* quoted string can contain any character except " itself */ BNF大家可能不熟悉,BNF其实是"Backus Naur Form"的缩写,最初是John Backus和Peter Naur提出的,是用来描述某指定语言语法的正式符号。先举个例子吧: cmd cmd /c dir cd C:\windows ; cmd /c dir cd "C:\Program Files\Informix" ; cmd /c dir cd "C:\Program Files\Pictures" ; "\\picard\Software\Graphic Utilities\PSP\psp.exe" Title.jpg 所有这些都是行之有效的命令行字符串。分析函数Parse()将这些命令行字符串分裂成3个部分:"directory", "command" and "arguments". 即:目录、命令和参数,任何特别的标记都将被剥去。所以如果你对上面例子中最后一个命令行字符串进行分析,你将得到如下结果: C:\Program Files\Pictures作为目录 \\picard\Software\Graphic Utilities\PSP\psp.exe作为命令 Title.jpg作为命令的参数 你可以传递一个完整的命令行字符串到Execute()函数,如果该命令行字符串的命令部分不是一个可执行的文件,那么Execute()函数将搜寻和此相关的可执行文件,如果Execute()的参数bWait是TRUE的话,Execute()将返回这次执行的exit code,否则返回进程的ID即process-ID (PID)。使用Wait()函数你能准确的等到某个进程的结束,并且你只需要提供该进程的ID即可。为了检查某程序是否在运行,可以用IsProgramRunning()函数,如果你输入一个可执行文件名字,该函数将检查进程列表,如果该进程当前正在运行就返回该进程的ID,没有运行的话就返回0。 如果你正在开发这样一个程序,注意假设条件: 1 该程序没有提供窗口 2 该程序在每台PC上只能运行一次 那么你将不能用FindWindow()函数来得到当前该程序是否运行,并且互斥体mutexes或相似资源也将鞭长莫及。在这种情况下,你可以使用如下代码: TCHAR szName[1024]; GetModuleFileName(0, szName, 1023); if( CProcessMgr().IsProgramRunning(szName) != DWORD(getpid()) ) { // the application is already running on this machine } 上面的代码之所以能工作,是因为在进程列表中新创建的进程总是在原先的进程之后,他们的ID是唯一的,即使同一个程序,ID也不会相同。最后SwitchProcessIntoForeground()函数可以把进程窗口激活并把它带到屏幕最前,如果进程的主窗口被最小化,那么SwitchProcessIntoForeground()函数将其恢复到上一步的状态,如果IsProgramRunning()标志某个进程正在运行,但是SwitchProcessIntoForeground()返回"I cannot switch to that process",这表示这个进程可能是个DDE/OLE 服务程序,这类程序通常只有一个隐藏窗口或者没有窗口(NT服务实例)。 |
但总感觉没有用.现在我正在学Windows编程,看到了一些创建进程和结束
进程的函数.所以就想自己也做一个QQ升级器来玩玩.
但编完之后发现好象有点小Bug.
那就是程序运行之后它可以创建QQ进程,但是好象关不掉(其实是关掉了,
因为进程里面只有一个qq.exe,有可能有两个,我所编的程序中的关闭进程,
点像是在"任务管理器"中关掉的一样.大家可以试一下.).
望高手指点.
编程环境vc++6.0
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
using namespace std;
// 结束进程
BOOL TerminateProcessFromId( DWORD dwId )
{
BOOL bRet = FALSE;
HANDLE hProcess = ::OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwId );
if ( hProcess != NULL )
{
bRet = ::TerminateProcess( hProcess, 0 );
}
::CloseHandle( hProcess );
return bRet;
}
// 创建QQ进程
DWORD CreateQQProcess()
{
char szQQPath[] = "c:\\program files\\tencent\\qq\\qq.exe"; // qq.exe的路径
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof( si ) };
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = TRUE;
BOOL bRet =::CreateProcess(
NULL,
szQQPath,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);
if ( bRet )
{
::CloseHandle( pi.hThread );
::CloseHandle( pi.hProcess );
return pi.dwProcessId;
}
else
{
cout << " QQ.exe的进程不能被创建. " << endl;
cout << " 请检查QQ.exe的路径是否正确. " << endl;
return -1;
}
}
unsigned short CalTime( SYSTEMTIME time )
{
unsigned short interval;
interval = time.wMinute * 60 + time.wSecond;
return interval;
}
int main( int argc, char *argv[] )
{
DWORD gIntervaltime;
DWORD dProId ;
cout << "--------------------------- QQ 升级器 v1.0---------------------------------" << endl;
cout << "--------------------------作者:blacksource--------------------------------" << endl;
cout << " 在作用该软件之前请确定你已经登陆过QQ,并且已选择了“记住密码” " << endl;
cout << endl << " 请输入间隔时间,单位为微秒: " ;
cin >> gIntervaltime;
CreateQQProcess();
while( 1 )
{
if ( (dProId = CreateQQProcess()) == -1 )
break;
::Sleep( gIntervaltime );
if ( !TerminateProcessFromId( dProId ) )
{
cout << "QQ进程不能被并闭. "<< endl;
break;
}
}
return 0;
}
简单的脚本可以达到一样的效果
var sh=new ActiveXObject("Wscript.shell");
sh.run("c:\\program files\\tencent\\qq\\qq.exe",0);
保存成js文件,用Wscript或Csrcipt解析就可以了
浙公网安备 33010602011771号