1. 程式人生 > >PB 依據指定應用程式檔名返回PID

PB 依據指定應用程式檔名返回PID

在做專案的二次開發中需要用到使用PB查詢應用程式名稱返回的PID, 主要參考兩個論壇的帖子地址如下,因為一個是VB環境下的,各種變數型別與PB不同,需要進行轉換,經過多次測試,整了一個整天終於搞定了,現把原始碼分享出來,以備後用。

主要有三個函式 f_getpid, f_getpidusr , f_getuser

函式中需要引用的結構體

global type s_process from structure
	unsignedlong		structsize
	unsignedlong		usage
	unsignedlong		processid
	unsignedlong		defaultheapid
	unsignedlong		moduleid
	unsignedlong		threads
	unsignedlong		parentprocessid
	unsignedlong		classbase
	unsignedlong		flags
	character		filename[256]
end type

global type sid_and_attributes from structure
	unsignedlong		SID
	unsignedlong		Attributes
end type

global type token_user from structure
	sid_and_attributes		User
	character		SID[500]
end type

需要註冊的API函式有

Function Long CreateToolhelp32Snapshot(Long Flags, Long ProcessId) Library "kernel32.dll" ALIAS FOR "CreateToolhelp32Snapshot;Ansi"
Function Integer Process32First(ULong Snapshot, Ref s_Process Process) Library "kernel32.dll" ALIAS FOR "Process32First;Ansi"
Function Integer Process32Next(ULong Snapshot, Ref s_Process Process) Library "kernel32.dll" ALIAS FOR "Process32Next;Ansi"
FUNCTION ulong WNetGetUser(ref string lpName,ref string lpUserName,ref ulong lpnLength) LIBRARY "mpr.dll" ALIAS FOR "WNetGetUserA;Ansi"
FUNCTION ulong OpenProcess(ulong dwDesiredAccess,ulong bInheritHandle,ulong dwProcessId) LIBRARY "kernel32.dll" ALIAS FOR "OpenProcess;Ansi"
Function long OpenProcessToken(ulong ProcessHandle, ulong DesiredAccess, ref ulong TokenHandle) Library "advapi32.dll" ALIAS FOR "OpenProcessToken;Ansi"
Function Long GetTokenInformation(Long TokenHandle, Long TokenInformationClass, ref token_user TokenInformation , Long TokenInformationLength,ref Long ReturnLength) Library "advapi32.dll"
Function Long LookupAccountSidA(string lpSystemName, ulong Sid, ref string Name, ref Long cbName,ref string DomainName,ref Long cbDomainName, ref Int peUse) Library "advapi32.dll"  alias for "LookupAccountSidA;ansi"

1. f_getpid(String exename) 查詢檔名為exename的程序的pid, 引數為可執行程式的檔名

global type f_getpid from function_object
end type

forward prototypes
global function unsignedlong f_getpid (string as_exename)
end prototypes

global function unsignedlong f_getpid (string as_exename);s_Process lst_Process
String ls_filename[1000] ,ls_curexename,ls_usr
ULong ln_ProcessID,ln_SameCount,ln_Snapshot,ln_Circle,ln_Count,ul_PID,hProcess
long l_pid

ul_PID = 0
ln_Snapshot = CreateToolhelp32Snapshot(2,0)
//建立快照失敗
IF (ln_Snapshot < 1) THEN RETURN 0
//建立快照失敗 296是windows決定的
lst_Process.StructSize = 296

IF Process32First(ln_Snapshot,lst_Process) = 0 THEN RETURN 0

//列舉當前許可權下的程序 

DO WHILE 1 = 1
	IF Process32Next(ln_Snapshot,lst_Process) = 0 THEN EXIT
	ln_Count = ln_Count + 1
	ls_filename[ln_Count] = lst_Process.Filename
	
	
	IF Lower(ls_filename[ln_Count]) = lower(as_exename) THEN
		//取得程序號 
		ul_PID = lst_Process.ProcessID
		//取得該程序的使用者
		ls_usr = f_getpidusr(ul_PID)
		if ls_usr = f_getuser() then
//			f_msg(getpidusr(ul_PID))
			l_pid = long(string(ul_PID))
		end if
		//MessageBox(string(ul_PID),ls_FileName[ln_Count]) 
	END IF
LOOP

long l_i 
l_i = 1;

RETURN l_pid
end function
2. f_getpidusr(ulong processid) 查詢程序id為processid的系統使用者名稱, 引數為待查詢的使用者程序的pid
global type f_getpidusr from function_object
end type

forward prototypes
global function string f_getpidusr (unsignedlong processid)
end prototypes

global function string f_getpidusr (unsignedlong processid);string ls_return,sAcctName2,sDomainName,sysname
ulong hProcess,hToken
long IR,GR,cbBuff,cbAcctName,cbDomainName
int peUse
token_user usr

Constant ulong TOKEN_ADJUST_PRIVILEGES = 32
Constant ulong TOKEN_QUERY = 8
constant long PROCESS_QUERY_INFORMATION = 1024

hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, processid)		//使該程序可讀
if hProcess > 0 then
//	f_msg(string(hProcess))
	IR = OpenProcessToken(hProcess, TOKEN_QUERY + TOKEN_ADJUST_PRIVILEGES, hToken)
//	f_msg("Token:" + string(hToken))
	if IR > 0 then
		GR = GetTokenInformation(hToken, 1, usr, 256, cbBuff)
//		f_msg(string(GR))
		if GR > 0 then
			sAcctName2 = space(255)
			sDomainName = space(255)
			cbAcctName  = 255
			cbDomainName = 255
			long sid
			sid = usr.user.sid
			LookupAccountSidA(sysname,sid,sAcctName2,cbAcctName,sDomainName,cbDomainName,peUse)
			ls_return = sAcctName2
//			f_msg(sAcctName2)
		end if
	end if
//			if IR =0 then
//				ll_last_error = GetLastError()
//				f_msg(string(ll_last_error))
//			end if
end if

return ls_return
end function

3. f_getuser() 查詢當前登入的系統使用者名稱

global type f_getuser from function_object
end type

forward prototypes
global function string f_getuser ()
end prototypes

global function string f_getuser ();string ls_name, ls_username
ulong ll_len
ll_len = 256
ls_username = space(ll_len)
setnull(ls_name)
WNetGetUser(ls_Name,ls_UserName,ll_Len) 
//messagebox("系統登入使用者名稱",ls_username)
return ls_username
end function