Delphi - 较低级别和较高级别进程之间的进程间通信
Delphi - Inter Process communication between lower level and higher level processes
我在 delphi 中有一个 运行 具有管理员权限的小型 vcl 应用程序,此应用程序仅接收消息和戳鼠标事件。
第二个应用程序 运行 具有普通用户权限(低于第一个),此应用程序无法向第一个应用程序发送消息。
我确定原因是权限级别,较高和较低,因为如果我 运行 两者都具有较低或较高的权限,则它们会成功通信。
我如何进行 IPC 才能将消息从最低级别的应用程序发送到更高级别的应用程序?
或者不可能?
这是我用来发送消息的方式:
上位app使用此代码处理winapi.messages:
procedure TfrMouseDriver.WMCopyData(var Message: TWMCopyData);
var
S: WideString;
cmd, sX, sY: String;
s2,F: String;
WParam: WideString;
i, z, X, Y: integer;
begin
X := 1;
Y := 1;
if true then
begin
s:= PWideChar(Message.CopyDataStruct.lpData);
s2:= PChar(Message.CopyDataStruct.lpData);
...
而最底层的应用程序是这样发送消息的:
procedure TfrPenDriver.btnIPCClick(Sender: TObject);
var
CopyData: CopyDataStruct;
hMouse : HWND;
Msg : WideString;
begin
Msg := 'CM_MOVE:000500:000230';
hMouse := FindWindow(PCHAR('TfrMouseDriver'),nil);
if hMouse > 0 then
begin
CopyData.dwData := 0;
CopyData.lpData := PWideChar(Msg);
CopyData.cbData := (1 + Length(Msg))*SizeOf(WideChar);
Winapi.Windows.SendMessage(hMouse, WM_COPYDATA, 0, LPARAM(@CopyData));
end;
end;
我正在寻找在具有不同用户级别的应用程序之间执行 IPC 的方法,其中最低级别需要发送到更高级别的应用程序。
用于本地机器进程间通信的 Mailslots 是您最好的选择,因为它们很简单,并且它们是通过 Windows 中的驱动程序实现的,就像管道一样。此驱动程序在基于 NT 的系统上是 msfs.sys。您不需要启用任何特殊权限即可创建邮筒,read/write 等,它们可以在任何进程类型、应用程序级别和任何外部会话中工作。
Window 句柄 (HWND) 是特定于会话的,不会跨其他用户会话工作,因此在这种情况下,您 运行 使用 WM_COPYDATA 会遇到问题,因为它依赖于 window handle 并且如前所述,UIPI 对更现代 Windows 操作系统的限制可能是个问题。
另一个 WM_COPYDATA 不好的原因是...假设您 运行 在另一个进程的上下文中执行可执行代码(比如 csrss 等系统进程)那不是 "interactive" 过程。也许你已经注入了一个 DLL 并想发送一个带有 WM_COPYDATA 的 IPC 消息......你可以预期进程崩溃或者根据进程的关键性,预期 BSOD。发生这种情况是因为这些进程不喜欢 user32.dll API 调用,例如 WM_COPYDATA 作为 IPC 系统所依赖的 SendMessage。
坚持使用邮筒。
我在 delphi 中有一个 运行 具有管理员权限的小型 vcl 应用程序,此应用程序仅接收消息和戳鼠标事件。 第二个应用程序 运行 具有普通用户权限(低于第一个),此应用程序无法向第一个应用程序发送消息。 我确定原因是权限级别,较高和较低,因为如果我 运行 两者都具有较低或较高的权限,则它们会成功通信。 我如何进行 IPC 才能将消息从最低级别的应用程序发送到更高级别的应用程序? 或者不可能?
这是我用来发送消息的方式:
上位app使用此代码处理winapi.messages:
procedure TfrMouseDriver.WMCopyData(var Message: TWMCopyData);
var
S: WideString;
cmd, sX, sY: String;
s2,F: String;
WParam: WideString;
i, z, X, Y: integer;
begin
X := 1;
Y := 1;
if true then
begin
s:= PWideChar(Message.CopyDataStruct.lpData);
s2:= PChar(Message.CopyDataStruct.lpData);
...
而最底层的应用程序是这样发送消息的:
procedure TfrPenDriver.btnIPCClick(Sender: TObject);
var
CopyData: CopyDataStruct;
hMouse : HWND;
Msg : WideString;
begin
Msg := 'CM_MOVE:000500:000230';
hMouse := FindWindow(PCHAR('TfrMouseDriver'),nil);
if hMouse > 0 then
begin
CopyData.dwData := 0;
CopyData.lpData := PWideChar(Msg);
CopyData.cbData := (1 + Length(Msg))*SizeOf(WideChar);
Winapi.Windows.SendMessage(hMouse, WM_COPYDATA, 0, LPARAM(@CopyData));
end;
end;
我正在寻找在具有不同用户级别的应用程序之间执行 IPC 的方法,其中最低级别需要发送到更高级别的应用程序。
用于本地机器进程间通信的 Mailslots 是您最好的选择,因为它们很简单,并且它们是通过 Windows 中的驱动程序实现的,就像管道一样。此驱动程序在基于 NT 的系统上是 msfs.sys。您不需要启用任何特殊权限即可创建邮筒,read/write 等,它们可以在任何进程类型、应用程序级别和任何外部会话中工作。
Window 句柄 (HWND) 是特定于会话的,不会跨其他用户会话工作,因此在这种情况下,您 运行 使用 WM_COPYDATA 会遇到问题,因为它依赖于 window handle 并且如前所述,UIPI 对更现代 Windows 操作系统的限制可能是个问题。
另一个 WM_COPYDATA 不好的原因是...假设您 运行 在另一个进程的上下文中执行可执行代码(比如 csrss 等系统进程)那不是 "interactive" 过程。也许你已经注入了一个 DLL 并想发送一个带有 WM_COPYDATA 的 IPC 消息......你可以预期进程崩溃或者根据进程的关键性,预期 BSOD。发生这种情况是因为这些进程不喜欢 user32.dll API 调用,例如 WM_COPYDATA 作为 IPC 系统所依赖的 SendMessage。
坚持使用邮筒。