急!!!!dll全局变量问题(50分)

  • 主题发起人 主题发起人 zzb1984
  • 开始时间 开始时间
Z

zzb1984

Unregistered / Unconfirmed
GUEST, unregistred user!
在dll我设了个全局变量path<br>我在dll的函数a中改变了path的值<br>&nbsp; &nbsp; path := GetCurrentDir;<br>但当我在函数b中的<br>if length(path) &lt;= 0 then<br>&nbsp; path := 'null';<br>path居然为'null'<br><br>难道在dll中无法在不同函数中共享全局变量吗<br>全部代码如下<br>unit HKProc;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, Dialogs, SysUtils, TLHelp32;<br><br>var<br>&nbsp; hNextHookProc: HHook;<br>&nbsp; procSaveExit: Pointer;<br>&nbsp; userName, path : string;<br>&nbsp; lpBuffer :array[1..64] of Char;<br>&nbsp; nSize :Cardinal;<br>&nbsp; myfile : textfile;<br><br>function shellproc(iCode: Integer;<br>&nbsp; wParam: WPARAM;<br>&nbsp; lParam: LPARAM): LRESULT; stdcall; export;<br>function EnableHotKeyHook: BOOL; export;<br>function DisableHotKeyHook: BOOL; export;<br>procedure HotKeyHookExit; far;<br><br><br>implementation<br><br>function shellproc(iCode: Integer;<br>&nbsp; wParam: WPARAM;<br>&nbsp; lParam: LPARAM): LRESULT; stdcall; export;<br>var<br>&nbsp; szTitle:string; &nbsp; &nbsp; //当前窗口名称<br>&nbsp; temp : TDateTime;<br>&nbsp; processPath:string;<br>&nbsp; Handler : THandle;<br>begin<br>&nbsp; Result := 0;<br>&nbsp; If iCode &lt; 0 Then<br>&nbsp; begin<br>&nbsp; &nbsp; Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);<br>&nbsp; &nbsp; Exit;<br>&nbsp; end<br>&nbsp; else if iCode=HSHELL_WINDOWCREATED then<br>&nbsp; begin<br>&nbsp; &nbsp; SetLength(szTitle, 255);<br>&nbsp; &nbsp; SetLength(szTitle, GetWindowText(wParam,pchar(szTitle),254));<br><br>{ &nbsp; &nbsp;nSize := 255;<br>&nbsp; &nbsp; GetUserName(@lpBuffer, nSize);<br>&nbsp; &nbsp; userName := Copy(lpBuffer, 1, nSize-1);<br>&nbsp; &nbsp; path := GetCurrentDir;<br>&nbsp; &nbsp; path:=path + '/' + userName + DateToStr(now()) +'.txt';<br>&nbsp; &nbsp; AssignFile(myfile, 'E:/delphiProgram/managerComputer/windowtext.txt');<br>&nbsp; &nbsp; append(myfile);<br>&nbsp; &nbsp; Writeln(myfile, Path );<br>&nbsp; &nbsp; CloseFile(myfile);<br>}<br><br>&nbsp; &nbsp; if length(path) &lt;= 0 then<br>&nbsp; &nbsp; &nbsp; path := 'null';<br>&nbsp; &nbsp; AssignFile(myfile, 'E:/delphiProgram/managerComputer/windowtext.txt');<br>&nbsp; &nbsp; append(myfile);<br>&nbsp; &nbsp; Writeln(myfile, Path );<br>&nbsp; &nbsp; CloseFile(myfile);<br><br>&nbsp; end;<br>end;<br><br><br>function EnableHotKeyHook: BOOL; export;<br>begin<br>&nbsp; &nbsp; nSize := 255;<br>&nbsp; &nbsp; GetUserName(@lpBuffer, nSize);<br>&nbsp; &nbsp; userName := Copy(lpBuffer, 1, nSize-1);<br>&nbsp; &nbsp; path := GetCurrentDir;<br>&nbsp; &nbsp; path:=path + '/' + userName + DateToStr(now()) +'.txt';<br>&nbsp; &nbsp; AssignFile(myfile, 'E:/delphiProgram/managerComputer/windowtext.txt');<br>&nbsp; &nbsp; append(myfile);<br>&nbsp; &nbsp; Writeln(myfile, Path );<br>&nbsp; &nbsp; CloseFile(myfile);<br><br>&nbsp; Result := False;<br>&nbsp; if hNextHookProc &lt;&gt; 0 then Exit;<br>&nbsp; // 挂上 WH_KEYBOARD 这型的 HOOK, 同时, 传回值必须保留下<br>&nbsp; // 来, 免得 HOOK 呼叫链结断掉<br>&nbsp; hNextHookProc := SetWindowsHookEx(WH_SHELL,<br>&nbsp; &nbsp; shellproc,<br>&nbsp; &nbsp; HInstance,<br>&nbsp; &nbsp; 0);<br>&nbsp; Result := hNextHookProc &lt;&gt; 0;<br>end;<br><br><br>function DisableHotKeyHook: BOOL; export;<br>begin<br>&nbsp; if hNextHookProc &lt;&gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; UnhookWindowshookEx(hNextHookProc); &nbsp;// 解除 Keyboard Hook<br>&nbsp; &nbsp; hNextHookProc := 0;<br>&nbsp; &nbsp; MessageBeep(0);<br>&nbsp; &nbsp; MessageBeep(0);<br>&nbsp; end;<br>&nbsp; Result := hNextHookProc = 0;<br>&nbsp;end;<br><br>procedure HotKeyHookExit;<br>begin<br>&nbsp; // 如果忘了解除 HOOK, 自动代理解除的动作<br>&nbsp; if hNextHookProc &lt;&gt; 0 then DisableHotKeyHook;<br>&nbsp; ExitProc := procSaveExit;<br>end;<br><br>end.<br><br>
 
当然是null了<br><br>用内存映像吧
 
如何内存映像<br>请赐教
 
我想应该没问题吧。来测测先。
 
我是想把用钩子记录下的窗口标题栏名称保存到dll所在的文件夹<br>一开始,我在shellproc用path获得dll所在的文件夹的路径,path := GetCurrentDir;<br>结果当我打开一个网页时, &nbsp; &nbsp;<br>path:= H:/program files/internet explorer/IEXPLORE.EXE<br><br>为此我到EnableHotKeyHook:中,全局变量path := GetCurrentDir;<br>的确获得dll所在的文件夹的路径,但是通过全局变量path传不进shellproc<br>在shellproc中path 未改变,仍为空串<br><br>
 
只要在shellproc用path获得dll所在的文件夹的路径<br>用什么方法都行<br>
 
为什么会这样,什么原因,<br>按道理他和 hNextHookProc 一样,为什么 hNextHookProc可以,他不可以<br>难道是String类型的问题。
 
我知道了,你的Path是在EnableHotKeyHook中初始化的,而这个函数是在你的<br>启动Hook的进程中执行的,也就是说其他的进程中全为空。<br><br>我想把Path初始化放入Hook的回调函数中应该就好了。
 
修改后代码,加了个全局变量IsExistPath,检测Path是否初始化过。<br>修改了Hook的回调函数:<br><br>function shellproc(iCode: Integer;<br>&nbsp;wParam: WPARAM;<br>&nbsp;lParam: LPARAM): LRESULT; stdcall; export;<br>var<br>&nbsp;szTitle:string; &nbsp; &nbsp; //当前窗口名称<br>&nbsp;temp : TDateTime;<br>&nbsp;processPath:string;<br>&nbsp;Handler : THandle;<br>begin<br>&nbsp;Result := 0;<br>&nbsp;If iCode &lt; 0 Then<br>&nbsp;begin<br>&nbsp; &nbsp;Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);<br>&nbsp; &nbsp;Exit;<br>&nbsp;end<br>&nbsp;else if iCode=HSHELL_WINDOWCREATED &nbsp; then<br>&nbsp;begin<br>&nbsp; &nbsp;SetLength(szTitle, 255);<br>&nbsp; &nbsp;SetLength(szTitle, GetWindowText(wParam,pchar(szTitle),254));<br><br>&nbsp; &nbsp;if not IsExistpath then<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; nSize := 255;<br>&nbsp; &nbsp; GetUserName(@lpBuffer, nSize);<br>&nbsp; &nbsp; userName := Copy(lpBuffer, 1, nSize-1);<br>&nbsp; &nbsp; path := GetCurrentDir;<br>&nbsp; &nbsp; path:=path + '/' + userName + DateToStr(now()) +'.txt';<br>&nbsp; &nbsp; isExistpath:=true;<br>&nbsp; &nbsp;end;<br><br>&nbsp; &nbsp;if length(path) &lt;= 0 then<br>&nbsp; &nbsp; &nbsp;path := 'null';<br>&nbsp; &nbsp;AssignFile(myfile, 'E:/pp.txt');<br>&nbsp; &nbsp;append(myfile);<br>&nbsp; &nbsp;Writeln(myfile, Path );<br>&nbsp; &nbsp;Writeln(myfile, szTitle );<br>&nbsp; &nbsp;CloseFile(myfile);<br><br>&nbsp;end;<br>end;<br>
 
也许<br>我试了一下内存映射,好像还是不行<br>&nbsp; hMapFile : THandle;<br>&nbsp; MapFilePointer: pointer;<br><br>function EnableHotKeyHook: BOOL; export;<br>var<br>&nbsp; hMapFile : THandle;<br>begin<br>&nbsp; &nbsp; nSize := 255;<br>&nbsp; &nbsp; GetUserName(@lpBuffer, nSize);<br>&nbsp; &nbsp; userName := Copy(lpBuffer, 1, nSize-1);<br>&nbsp; &nbsp; path := GetCurrentDir;<br>&nbsp; &nbsp; path:=path + '/' + userName + DateToStr(now()) +'.txt';<br><br>&nbsp;hMapFile := CreateFileMapping (<br>&nbsp; &nbsp;$FFFFFFFF, // 特殊内存映射句柄<br>&nbsp; &nbsp;nil, page_ReadWrite, 0,10000,<br>&nbsp; &nbsp;'DdhDemoMappedFile'); // 文件名<br>&nbsp;if hMapFile &lt;&gt; 0 then<br>&nbsp; &nbsp;MapFilePointer := MapViewOfFile (<br>&nbsp; &nbsp; &nbsp;hMapFile, // 上面映象文件的句柄<br>&nbsp; &nbsp; &nbsp;File_Map_All_Access,<br>&nbsp; &nbsp; &nbsp;0, 0, 0) // 访问整个映象文件<br>&nbsp;else<br>&nbsp; &nbsp;ShowMessage ('hMapFile = 0');<br>&nbsp;if MapFilePointer = nil then<br>&nbsp; &nbsp;ShowMessage ('MapFilePointer = nil');<br><br>&nbsp;StrCopy ( PChar (MapFilePointer), &nbsp;PChar (path) );//把内容写入共享内存<br>&nbsp;temp := PChar (MapFilePointer);//从共享内存读出内容<br><br>if length(temp) &lt;= 0 then<br>&nbsp; temp := 'null';<br><br>&nbsp; &nbsp; AssignFile(myfile, 'E:/delphiProgram/managerComputer/windowtext.txt');<br>&nbsp; &nbsp; append(myfile);<br>&nbsp; &nbsp; Writeln(myfile, temp );<br>&nbsp; &nbsp; CloseFile(myfile);<br>&nbsp; &nbsp; <br>&nbsp; Result := False;<br>&nbsp; if hNextHookProc &lt;&gt; 0 then Exit;<br>&nbsp; // 挂上 WH_KEYBOARD 这型的 HOOK, 同时, 传回值必须保留下<br>&nbsp; // 来, 免得 HOOK 呼叫链结断掉<br>&nbsp; hNextHookProc := SetWindowsHookEx(WH_SHELL,<br>&nbsp; &nbsp; shellproc,<br>&nbsp; &nbsp; HInstance,<br>&nbsp; &nbsp; 0);<br>&nbsp; Result := hNextHookProc &lt;&gt; 0;<br>end;<br><br>在shellproc中<br>&nbsp;path := PChar (MapFilePointer);//从共享内存读出内容<br>在shellproc中path 未改变,仍为空串<br><br>
 
看了你上面的说明,我知道了。你要存放的目录,<br>你只有用内存影射吧。
 
我在shellproc用path获得dll所在的文件夹的路径,path := GetCurrentDir;<br>结果当我打开一个网页时, &nbsp; &nbsp;<br>path:= H:/program files/internet explorer/IEXPLORE.EXE<br>得不到dll所在的文件夹的路径
 
我试了一下内存映射,好像还是不行<br>
 
你的难道<br>是对的<br><br>Dll是无法使用全局变量,<br><br>只有用内存映射文件的方法<br><br>也可以,把全局变量最为一个参数传入,这样可以在调用者这边维护她
 
偶写的自己用的使用内存映像的几个函数,给你了<br>// --------------------------------WriteShareData-------------------------------<br>// 名 &nbsp; &nbsp;称:WriteShareData<br>// 功 &nbsp; &nbsp;能:写内存映像文件,保存一个整形数据<br>// 参 &nbsp; &nbsp;数:<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ShareName &nbsp; &nbsp; &nbsp; &nbsp; 内存映像文件的唯一标示<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Data &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;要写入的数据<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DataSize &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;数据的大小<br>// 返 回 值:内存映像的句柄,调用者需要保存,在它不再使用后要CloseHandle<br>// 日 &nbsp; &nbsp;期:2004.02.05<br>// 修 &nbsp; &nbsp;改:????.??.??<br>function WriteShareData(ShareName: pchar; Data: pointer; DataSize: Cardinal): THandle; export;<br>// --------------------------------ReadShareData--------------------------------<br>// 名 &nbsp; &nbsp;称:ReadShareData<br>// 功 &nbsp; &nbsp;能:写内存映像文件,保存一个整形数据<br>// 参 &nbsp; &nbsp;数:<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ShareName &nbsp; &nbsp; &nbsp; &nbsp; 内存映像文件的唯一标示,必须是已经存在的<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Data &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;读出的数据缓冲区<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DataSize &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;要读出数据缓冲的大小,调用者必须知道<br>// 返 回 值:无<br>// 日 &nbsp; &nbsp;期:2004.02.05<br>// 修 &nbsp; &nbsp;改:????.??.??<br>procedure ReadShareData(ShareName: pchar; Data: pointer; DataSize: Cardinal); export;<br>// --------------------------------WriteShareInteger----------------------------<br>// 名 &nbsp; &nbsp;称:WriteShareInteger<br>// 功 &nbsp; &nbsp;能:写内存映像文件,保存一个整形数据<br>// 参 &nbsp; &nbsp;数:<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ShareName &nbsp; &nbsp; &nbsp; &nbsp; 内存映像文件的唯一标示<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;h &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 要写入的数据<br>// 返 回 值:内存映像的句柄,调用者需要保存,在它不再使用后要CloseHandle<br>// 日 &nbsp; &nbsp;期:2004.02.05<br>// 修 &nbsp; &nbsp;改:????.??.??<br>function WriteShareInteger(ShareName: pchar; h: integer): THandle; export;<br>// --------------------------------ReadShareInteger-----------------------------<br>// 名 &nbsp; &nbsp;称:ReadShareInteger<br>// 功 &nbsp; &nbsp;能:读内存映像文件中的整形数据<br>// 参 &nbsp; &nbsp;数:<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ShareName &nbsp; &nbsp; &nbsp; &nbsp; 内存映像文件的唯一标示,必须是已经存在的<br>// 返 回 值:内存映像文件中的数据<br>// 日 &nbsp; &nbsp;期:2004.02.05<br>// 修 &nbsp; &nbsp;改:????.??.??<br>function ReadShareInteger(ShareName: pchar): integer; export;<br><br><br><br><br>function WriteShareData(ShareName: pchar; Data: pointer; DataSize: Cardinal): THandle;<br>var<br>&nbsp; tmpData: pointer;<br>begin<br>&nbsp; result := CreateFileMapping(DWord($FFFFFFFF), nil, PAGE_READWRITE, 0,<br>&nbsp; &nbsp; DataSize, ShareName);<br>&nbsp; tmpData := MapViewofFile(result, FILE_MAP_WRITE, 0, 0, 0);<br>&nbsp; move(Data^, tmpData^, DataSize);<br>&nbsp; UnMapViewofFile(tmpData);<br>end;<br><br>procedure ReadShareData(ShareName: pchar; Data: pointer; DataSize: Cardinal);<br>var<br>&nbsp; hMap: THandle;<br>&nbsp; tmpData: pointer;<br>begin<br>&nbsp; hMap := CreateFileMapping(DWord($FFFFFFFF), nil, PAGE_READWRITE,<br>&nbsp; &nbsp; 0, DataSize, ShareName);<br>&nbsp; try<br>&nbsp; &nbsp; tmpData := MapViewofFile(hMap, FILE_MAP_READ, 0, 0, 0);<br>&nbsp; &nbsp; move(tmpData^, Data^, DataSize);<br>&nbsp; &nbsp; UnMapViewofFile(tmpData);<br>&nbsp; finally<br>&nbsp; &nbsp; CloseHandle(hMap);<br>&nbsp; end;<br>end;<br><br>function ReadShareInteger(ShareName: pchar): integer;<br>begin<br>&nbsp; ReadShareData(ShareName, @result, sizeof(integer));<br>end;<br><br>function WriteShareInteger(ShareName: pchar; h: integer): THandle;<br>begin<br>&nbsp; result := WriteShareData(ShareName, @h, sizeof(integer));<br>end;
 
hMapFile : THandle;<br>&nbsp;MapFilePointer: pointer;<br><br>function EnableHotKeyHook: BOOL; export;<br>var<br>&nbsp;hMapFile : THandle;<br>begin<br>&nbsp; &nbsp;nSize := 255;<br>&nbsp; &nbsp;GetUserName(@lpBuffer, nSize);<br>&nbsp; &nbsp;userName := Copy(lpBuffer, 1, nSize-1);<br>&nbsp; &nbsp;path := GetCurrentDir;<br>&nbsp; &nbsp;path:=path + '/' + userName + DateToStr(now()) +'.txt';<br><br>&nbsp; &nbsp; hMapFile := WriteShareData('monitor', @path, 255);<br>&nbsp; &nbsp; ReadShareData('monitor', @temp, 255);<br>&nbsp; &nbsp; if length(temp) &lt;= 0 then<br>&nbsp; &nbsp; &nbsp; &nbsp;temp := 'null';<br><br>&nbsp; &nbsp;AssignFile(myfile, 'E:/delphiProgram/managerComputer/windowtext.txt');<br>&nbsp; &nbsp;append(myfile);<br>&nbsp; &nbsp;Writeln(myfile, temp );<br>&nbsp; &nbsp;CloseFile(myfile);<br>&nbsp; &nbsp;<br>&nbsp;Result := False;<br>&nbsp;if hNextHookProc &lt;&gt; 0 then Exit;<br>&nbsp;// 挂上 WH_KEYBOARD 这型的 HOOK, 同时, 传回值必须保留下<br>&nbsp;// 来, 免得 HOOK 呼叫链结断掉<br>&nbsp;hNextHookProc := SetWindowsHookEx(WH_SHELL,<br>&nbsp; &nbsp;shellproc,<br>&nbsp; &nbsp;HInstance,<br>&nbsp; &nbsp;0);<br>&nbsp;Result := hNextHookProc &lt;&gt; 0;<br>end;<br><br>在shellproc中<br>&nbsp; &nbsp; ReadShareData('monitor', @path, 255);<br><br>改完后运行<br>主函数执行到EnableHotKeyHook提示"access violation at ....."<br><br><br><br>
 
你写的内存映射,对吗?<br><br>应该是先Open,失败然后Create<br>你在启动Hook中Create了,记下变量在回调函数中没用,因为是不同进程.<br>所以映射进每个进程时要,OpenFileMapping.初始化变量MapFilePointer<br><br>所以,你应该在Dll的的Entry函数中初始化MapFilePointer(即OpenFileMapping)<br>或者回调函数中.<br>也就是说每个进程要OpenFileMapping一次.
 
&gt;&gt;fu_qi_ming<br>&nbsp; 按你的方法终于成功了<br>多谢!
 
多人接受答案了。
 
后退
顶部