回复 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