谁能将GetModuleFileName 开成AU3的?谢谢
本帖最后由 itljl 于 2009-5-23 16:59 编辑GetModuleFileName
函数说明:
Unit
Windows.Pas
Syntax
GetModuleFileName(
hModule: HINST; {a handle to the module}
lpFilename: PChar; {pointer to a null terminated string buffer}
nSize: DWORD {the size of the lpFilename buffer}
): DWORD; {returns the number of characters copied to the buffer}
Description
This function retrieves the full path and filename of the module identified by the handle in the hModule parameter.
Parameters
hModule: A handle to the module whose full path and filename are to be retrieved. If this parameter is set to zero, the function returns the full path and filename of the calling process.
lpFilename: A pointer to a null terminated string buffer that receives the path and filename.
nSize: Specifies the size of the buffer pointed to by the lpFilename parameter, in characters. If the returned path and filename is larger than this value, the string is truncated.
Return Value
If the function succeeds, it returns the number of characters copied to the buffer pointed to by the lpFilename parameter; otherwise it returns zero. To get extended error information, call the GetLastError function.
The Tomes of Delphi 3: Win32 Core API Help File by Larry Diehl
例子:
library Example;
uses
SysUtils,
Classes,
Windows,
Dialogs,
DLLAboutForm in 'DLLAboutForm.pas' {AboutBox};
{the exported functions}
exports
ShowAboutBox name 'ShowAboutBox';
{the DLL entry point procedure. this procedure will fire every time a
process or thread attaches to the DLL. if a process has attached to a DLL,
any newly created threads will automatically attach themselves}
procedure DLLMain(AttachFlag: DWORD);
begin
{display attachement type}
case AttachFlag of
DLL_PROCESS_ATTACH: MessageBox(0, 'Process: Attaching', 'Alert', MB_OK);
DLL_PROCESS_DETACH: MessageBox(0, 'Process: Detaching', 'Alert', MB_OK);
DLL_THREAD_ATTACH: MessageBox(0, 'Thread: Attaching' , 'Alert', MB_OK);
DLL_THREAD_DETACH: MessageBox(0, 'Thread: Detaching' , 'Alert', MB_OK);
end;
end;
begin
{initialize the DLL entry function}
DLLProc := @DLLMain;
{call the entry function upon DLL initialization}
DLLMain(DLL_PROCESS_ATTACH);
end.
Unit 2
{the prototype for the exported function}
function ShowAboutBox(ExampleName, Comments: ShortString): Boolean; export;
var
AboutBox: TAboutBox;
implementation
{$R *.DFM}
function ShowAboutBox(ExampleName, Comments: ShortString): Boolean;
begin
{initialize the function results}
Result := FALSE;
{create the about box form}
AboutBox := TAboutBox.Create(Application);
{initialize labels from the supplied strings}
AboutBox.ProductName.Caption := ExampleName;
AboutBox.Comments.Caption := Comments;
{show a modal about box}
AboutBox.ShowModal;
{release the form}
AboutBox.Release;
{indicate that the function completed}
Result := TRUE;
end;
Loading The Example Dynamic Link Library
procedure TForm1.Button1Click(Sender: TObject);
var
hMod: THandle; // holds the DLL handle
ModuleFileName: array of char; // holds the DLL name
{this is the prototype for the function imported from the DLL}
MyFunction: function(ExampleName, Comments: ShortString): Boolean;
begin
{explicitly load the DLL}
hMod := LoadLibrary('EXAMPLE.DLL');
if (hMod=0) then Exit;
{retrieve the address of the desired function}
@MyFunction := GetProcAddress(hMod, 'ShowAboutBox' );
{if the address was returned...}
if (@MyFunction<>nil) then
begin
{call the function to display an about box}
MyFunction('LoadLibrary Example','This example demonstrates loading '+
'a dynamic link library via the LoadLibrary function.');
{retrieve the module filename}
GetModuleFileName(GetModuleHandle('EXAMPLE.DLL'), @ModuleFileName,
SizeOf(ModuleFileName));
{display the DLLs name}
ShowMessage('The loaded DLL was: '+ModuleFileName);
end
else
{indicate an error}
ShowMessage('GetProcAddress Failed');
{free the DLL}
FreeLibrary(hMod);
end; #include <WinAPI.au3>
$hModule = _WinAPI_GetModuleHandle("user32.dll")
$sFileName = _GetModuleFileName($hModule)
MsgBox(0, $hModule, $sFileName)
Func _GetModuleFileName($hModule)
Local $sFileName
$sFileName = DllCall("Kernel32.dll", "int", "GetModuleFileName", _
"hWnd", $hModule, "str", "", "int", 260)
Return $sFileName
EndFunc ;==>_GetModuleFileName() 谢谢楼上的朋友啊!!!你是大好人.我现在来测试一下 这个函数我是用来检测一个程序的启动目录的.
但发现不行啊...我检测了一个EXE文件.显示模块错误.
RE: 谁能将GetModuleFileName 开成AU3的?谢谢
4# itljl你所需要的函数不是GetModuleFileName,而是GetModuleFileNameEx。#include <WinAPI.au3>
Func _QueryProcessExecutablePath($iProcessId)
Local $hProcess, $iResult
$iProcessId = ProcessExists($iProcessId)
If not $iProcessId Then Return SetError(2, 0, "")
$hProcess = _WinAPI_OpenProcess(0x400 + 0x10, 0, $iProcessId)
$iResult = DllCall("psapi.dll", "int", "GetModuleFileNameEx", _
"hWnd", $hProcess, "hWnd", 0, "str", "", "int", 260)
_WinAPI_CloseHandle($hProcess)
Return SetError(Not $iResult, 0, $iResult)
EndFunc ;==>_QueryProcessExecutablePath()
Msgbox(0, "", _QueryProcessExecutablePath("Notepad.exe")) 谢谢楼上这位朋友这么热心的解答,你这个是获取进程的路径.
仍然不是我需要的,获取进程的启动目录.
在这里,进程的启动目录指的是.
比如程序a.exe在c:\ 而a.exe启动了 d:\b.exe
b.exe的启动目录就是c:\
而不是文件所有目录d:\b.exe
再次感谢. 本帖最后由 pusofalse 于 2009-5-21 21:50 编辑
Re itljl:
这样也好办,只是一个获取父进程的过程,代码如下。#include <File.au3>
#include <File.au3>
#include <WinAPI.au3>
$tagProcessEntry = "dword dwSize;dword cntUsage;" & _
"dword th32ProcessID;ulong_ptr th32DefaultHeapID;" & _
"dword th32ModuleID;dword cntThreads;" & _
"dword th32ParentProcessID;long pcPriClassBase;" & _
"dword dwFlags;char szExeFile"
Func _CreateToolhelp32Snapshot($iProcessId, $iFlag)
Local $hSnap
$iProcessId = ProcessExists($iProcessId)
$hSnap = DllCall("kernel32.dll", "hWnd", "CreateToolhelp32Snapshot", _
"dword", $iFlag, "dword", $iProcessId)
Return $hSnap
EndFunc ;==>_CreateToolhelp32Snapshot()
Func _Process32First($hSnap)
Local $tProcessEntry = DllStructCreate($tagProcessEntry)
DllStructSetData($tProcessEntry, 1, DllStructGetSize($tProcessEntry))
DllCall("kernel32.dll", "int", "Process32First", _
"hWnd", $hSnap, _
"ptr", DllStructGetPtr($tProcessEntry))
Return $tProcessEntry
EndFunc ;==>_Process32First()
Func _Process32Next(ByRef $hSnap, ByRef $tProcessEntry)
Local $iResult
$iResult = DllCall("kernel32.dll", "int", "Process32Next", _
"hWnd", $hSnap, _
"ptr", DllStructGetPtr($tProcessEntry))
Return SetError(Not $iResult, 0, $iResult)
EndFunc ;==>_Process32Next()
Func _EnumChildProcesses($iProcessId)
Local $hSnap, $tProcessEntry, $aResult, $iProcess, $iParent
$hSnap = _CreateToolhelp32Snapshot(0, 2)
$tProcessEntry = _Process32First($hSnap)
$iProcessId = ProcessExists($iProcessId)
If not $iProcessId Then Return SetError(@error, 0, 0)
While True
_Process32Next($hSnap, $tProcessEntry)
If @error Then ExitLoop
$iProcess = DllStructGetData($tProcessEntry, "th32ProcessID")
$iParent = DllStructGetData($tProcessEntry, "th32ParentProcessID")
If $iParent = $iProcessId Then
$aResult = $iProcess
Redim $aResult
EndIf
WEnd
$tProcessEntry = 0
_WinAPI_CloseHandle($hSnap)
If Ubound($aResult) = 1 Then Return SetError(2, 0, 0)
Redim $aResult
Return SetError(0, Ubound($aResult), $aResult)
EndFunc ;==>_EnumChildProcesses()
Func _QueryParentProcess($iChildProcessId, $lparam = 0)
Local $iResult, $tProcess, $pProcess, $hSnap
Local $sResult, $sDrive, $sPath, $sName, $sExt
$iChildProcessId = ProcessExists($iChildProcessId)
If Not $iChildProcessId Then Return SetError(2, 0, 0)
$hSnap = _CreateToolhelp32Snapshot(0, 2)
$tProcess = _Process32First($hSnap)
While True
_Process32Next($hSnap, $tProcess)
If @error Then ExitLoop
$iProcessId = DllStructGetData($tProcess, "th32ProcessId")
$iParentId = DllStructGetData($tProcess, "th32ParentProcessID")
If $iProcessId = $iChildProcessId And $lparam = 0 Then
_WinAPI_CloseHandle($hSnap)
$sResult = _QueryParentProcess($iParentId, 1)
If $sResult Then Return $sResult
$sResult = _GetModuleFileNameEx($iProcessId)
_PathSplit($sResult, $sDrive, $sPath, $sName, $sExt)
Return $sDrive & $sPath
ElseIf $lparam = 1 And $iProcessId = $iChildProcessId Then
_WinAPI_CloseHandle($hSnap)
$sResult = _GetModuleFileNameEx($iProcessId)
_PathSplit($sResult, $sDrive, $sPath, $sName, $sExt)
Return $sDrive & $sPath
EndIf
WEnd
EndFunc ;==>_QueryParentProcess()
Func _GetModuleFileNameEx($iProcessId)
Local $iResult, $hProcess
$iProcessId = ProcessExists($iProcessId)
If Not $iProcessId Then Return SetError(2, 0, "")
$hProcess = _WinAPI_OpenProcess(0x400+0x10, 0, $iProcessId)
$iResult = DllCall("psapi.dll", "int", "GetModuleFileNameEx", _
"hWnd", $hProcess, "hWnd", 0, "str", "", "int", 260)
_WinAPI_CloseHandle($hProcess)
Return SetError(Not $iResult, 0, $iResult)
EndFunc ;==>_GetModuleFileNameEx()
Msgbox(0, _QueryParentProcess("qq.exe"), @error)
感谢楼上这位朋友的热心.
我运行后提示_CloseHandle($hSnap)
函数没有.
于是我用_WinAPI_CloseHandle($hSnap)
代替.
但发现只有极少数能得到目录,iexplore.exe是可以的.
其它好多程序都不行的.如qq.exe Re itljl:
确实是很大的BUG,对于没有父进程的进程,会返回空值。
已经修改,若有父进程,则返回父进程的目录,否则返回此进程的所在目录。 谢谢这位朋友,这问题,我都问得有点不好意思了。经过你的修改,问题确实已经解决。
我还想再问问,你是怎么学习写出这些API函数的。
我一般是通过GOOGLE。BAIDU相关的函数,还有就是MSDN。绝大部份资料都是在MSDN,全英文的。
相信你英文一定很好吧。
另外API还有地方和方法适合英文不好的我看懂吗? 其实需要获取进程目录的,用AU3调用API来实现,感觉确实够复杂的。简单点的用WMI,非常实用。当然有些进程是需要权限,还要用API提取权限。 11# sanhen
有相关的WMI例子吗?谢谢. 以前我记得发过在论坛的,不知现在还有没有了。记得也有其他兄弟发过的。 10# itljl
我也是在这3个地方学习的。说来惭愧,msdn中一半的单词看不懂,看不懂的函数再去csdn查下。越来越觉得英语的确重要,学习API函数,算上csdn,至少是中文的。没事常去这几个地方逛下,肯定大有收获。
页:
[1]