回复 3楼 pjtyzyq
草草整理一些进程相关代码作参考
** test.prg
#DEFINE MAX_PATH 260
#DEFINE TH32CS_SNAPPROCESS 0x00000002
#DEFINE STILL_ACTIVE 0x00000103
#DEFINE CREATE_NEW_CONSOLE 0x00000010
#DEFINE NORMAL_PRIORITY_CLASS 0x00000020
#DEFINE INFINITE -1
#DEFINE SEE_MASK_NOCLOSEPROCESS 0x00000040 && 使用hProcess成员
#DEFINE SEE_MASK_NOZONECHECKS 0x00800000 && 不检查,禁止安全警告
#DEFINE SEE_MASK_CONNECTNETDRV 0x00000080 && 验证共享和连接到驱动器
#DEFINE SEE_MASK_FLAG_NO_UI 0x00000400 && 不显示错误消息框
#DEFINE SW_SHOWNORMAL 1
#DEFINE PROCESS_ALL_ACCESS 0x001F0FFF
DECLARE LONG CreateMutex IN Kernel32 STRING@, LONG, STRING@
DECLARE LONG GetLastError IN Kernel32
DECLARE LONG CreateProcess IN Kernel32 STRING@, STRING@, STRING@, STRING@, LONG, LONG,;
STRING@, STRING@, STRING@, STRING@
DECLARE LONG GetExitCodeProcess IN Kernel32 LONG, LONG@
DECLARE LONG CloseHandle IN Kernel32 LONG
DECLARE LONG CreateToolhelp32Snapshot IN Kernel32 LONG, LONG
DECLARE LONG Process32First IN Kernel32 LONG, STRING@
DECLARE LONG Process32Next IN Kernel32 LONG, STRING@
DECLARE LONG OpenProcess IN Kernel32 LONG, LONG, LONG
DECLARE LONG TerminateProcess IN Kernel32 LONG, LONG
DECLARE LONG StrDup IN Shlwapi STRING@
DECLARE LONG WNetAddConnection2 IN Mpr.dll STRING@, STRING@, STRING@, LONG
DECLARE LONG WNetCancelConnection2 IN Mpr.dll STRING@, LONG, LONG
DECLARE LONG ShellExecuteEx IN Shell32 STRING@
DECLARE LONG WaitForSingleObject IN Kernel32 LONG, LONG
szPrg = JUSTSTEM(a程序[2])
dhMutex = CreateMutex(NULL, 0, @szPrg)
IF GetLastError() == 183 && ERROR_ALREADY_EXISTS
MESSAGEBOX(szPrg + " 已经运行")
_Close(dhMutex)
RETURN
ENDIF
? _TerminateProcess("QQ.exe") &&示例关闭QQ.exe进程
_Close(dhMutex)
RETURN
FUNCTION _Close(dhMutex)
CloseHandle(dhMutex)
RELEASE ALL
CLEAR ALL
IF _VFP.StartMode == 4
QUIT
ENDIF
ENDFUNC
**
** 运行一个外部程序
** _ShellExecuteEx(szFileName, @dhProcess)
** szFileName ... in, 进程执行文件名
** dhProcess .... out, 进程句柄
**
FUNCTION _ShellExecuteEx(szFileName, dhProcess)
LOCAL stSEI, dfMask, dhInstApp, szMsg
dfMask = SEE_MASK_NOCLOSEPROCESS;
+ SEE_MASK_FLAG_NO_UI;
+ SEE_MASK_CONNECTNETDRV;
+ SEE_MASK_NOZONECHECKS
* SHELLEXECUTEINFO 结构
stSEI = BINTOC(60, "4RS");
+ BINTOC(dfMask, "4RS") + REPLICATE(0h00, 8);
+ BINTOC(StrDup(@szFileName), "4RS") + REPLICATE(0h00, 8);
+ BINTOC(SW_SHOWNORMAL, "4RS") + REPLICATE(0h00, 28)
IF ShellExecuteEx(@stSEI) == 0
dhInstApp = CTOBIN(SUBSTR(stSEI, 33, 4), "4RS")
szMsg = ICASE(dhInstApp == 2, "没有找到文件",;
dhInstApp == 3, "没有找到路径",;
dhInstApp == 5, "拒绝访问",;
dhInstApp == 8, "内存不足",;
dhInstApp == 32, "没有找到动态链接库",;
dhInstApp == 26, "不能操作一个以打开的文件",;
dhInstApp == 27, "文件关联信息不完整",;
dhInstApp == 28, "DDE操作超时",;
dhInstApp == 29, "DDE操作失败",;
dhInstApp == 30, "DDE繁忙",;
dhInstApp == 31, "没有找到文件关联", "未知错误")
MESSAGEBOX("运行 " + szFileName + " 异常:" + szMsg, "提示")
RETURN .F.
ENDIF
dhProcess = CTOBIN(SUBSTR(stSEI, 57, 4), "4RS") &&输出进程句柄
RETURN .T.
ENDFUNC
**
** 创建一个新的进程和它的主线程
** _CreateProcess(szFileName, @dhProcess, @dhThread)
** szFileName ... in, 进程执行文件名
** dhProcess .... out, 进程句柄
** dhThread ..... out, 主线程句柄
**
FUNCTION _CreateProcess(szFileName, dhProcess, dhThread)
LOCAL stSI, stPI
* STARTUPINFO 结构
stSI = BINTOC(68, "4RS") + REPLICATE(0h00, 64)
* PROCESS_INFORMATION 结构
stPI = REPLICATE(0h00, 16)
IF CreateProcess(@szFileName,;
NULL,;
NULL,;
NULL,;
0,;
CREATE_NEW_CONSOLE,;
NULL,;
NULL,;
@stSI,;
@stPI) == 0
*NORMAL_PRIORITY_CLASS,;
*CREATE_NEW_CONSOLE,;
MESSAGEBOX("运行 " + szFileName + " 失败", "提示")
RETURN .F.
ENDIF
* 输出
dhProcess = CTOBIN(SUBSTR(stPI, 1, 4), "4RS")
dhThread = CTOBIN(SUBSTR(stPI, 5, 4), "4RS")
RETURN .T.
ENDFUNC
**
** 确定文件(szFileName)是否在运行的进程
** _IsProcessFileName(szFileName, @dhThread)
** dhProcess .... out, 进程句柄
**
FUNCTION _IsProcessFileName(szFileName, dhProcess)
LOCAL stPE, dhSnapshot, szExeFile, blRet, ddPID, ddRet
* PROCESSENTRY32 结构
stPE = BINTOC(36+MAX_PATH, "4RS") + REPLICATE(0h00, 32+MAX_PATH)
blRet = .F.
dhSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) && 进程快照
ddRet = Process32First(dhSnapshot, @stPE) && 第一个进程
DO WHILE ddRet > 0
szExeFile = RIGHT(stPE, MAX_PATH)
szExeFile = LEFT(szExeFile, AT(0h00, szExeFile)-1)
IF UPPER(szExeFile) == UPPER(szFileName)
ddPID = CTOBIN(SUBSTR(stPE,9,4), "4RS")
dhProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, ddPID)
blRet = .T.
EXIT
ENDIF
ddRet = Process32Next(dhSnapshot, @stPE) && 下一个进程
ENDDO
CloseHandle(dhSnapshot)
RETURN blRet
ENDFUNC
**
** 终止指定进程及其所有的线程
** _TerminateProcess(szFileName)
** szFileName ... in, 进程执行文件名
**
FUNCTION _TerminateProcess(szFileName)
LOCAL dhProcess, ddExitCode
dhProcess = 0
ddExitCode = 0
IF _IsProcessFileName(szFileName, @dhProcess)
GetExitCodeProcess(dhProcess, @ddExitCode)
TerminateProcess(dhProcess, ddExitCode)
RETURN .T.
ENDIF
RETURN .F.
ENDFUNC