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服务实例)。
最近QQ升级在网上抄的很热.所以前不久我也在网上down了一个来用用.
但总感觉没有用.现在我正在学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解析就可以了