如何从服务中收到OutputDebugString? [英] How can I receive OutputDebugString from service?
问题描述
我正在抓住所有 OutputDebugString 讯息(包括来自服务的)使用以下代码。它工作正常,直到我迁移到Windows 7.问题是,由于Windows Vista服务运行在低级Session#0有人说,这是不可能的抓住他们和一些它是。你怎么看 ?可以通过增加一些权限来修改以下代码: OutputDebugString 来自Session#0的消息?换一种说法;可以在Session#1的会话#0中共享DBWIN_BUFFER吗?
I'm trying to catch all OutputDebugString messages (including those from services) using the following code. It worked fine until I migrated to Windows 7. The problem is that since Windows Vista services are running in the low level Session #0 some people says that it's impossible to catch them and some that it is. What do you think ? Is it possible to modify the following code by increasing some rights to be able to receive OutputDebugString messages from the Session #0 ? In other words; is it possible to share DBWIN_BUFFER in the session #0 with Session #1 ?
我认为应该是可能的,因为例如DebugView可以做到这一点,我看不到任何服务助手将把这些消息(例如通过命名管道)从会话#0发送到会话#1,GUI运行。
I would say it should be possible because e.g. DebugView can do that and I can't see any service helper which would send those messages (e.g. through the named pipes) from the Session #0 to Session #1, where the GUI's running.
问题将在安全设置中是IMO。任何人都可以建议我如何修改它们?
The problem will be IMO in the security settings. Can anyone suggest me how to modify them ?
type
TODSThread = class(TThread)
protected
procedure Execute; override;
end;
...
procedure TODSThread.Execute;
var SharedMem: Pointer;
SharedFile: THandle;
WaitingResult: DWORD;
SharedMessage: string;
DataReadyEvent: THandle;
BufferReadyEvent: THandle;
SecurityAttributes: SECURITY_ATTRIBUTES;
SecurityDescriptor: SECURITY_DESCRIPTOR;
begin
SecurityAttributes.nLength := SizeOf(SECURITY_ATTRIBUTES);
SecurityAttributes.bInheritHandle := True;
SecurityAttributes.lpSecurityDescriptor := @SecurityDescriptor;
if not InitializeSecurityDescriptor(@SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) then
Exit;
if not SetSecurityDescriptorDacl(@SecurityDescriptor, True, nil, False) then
Exit;
BufferReadyEvent := CreateEvent(@SecurityAttributes, False, True, 'DBWIN_BUFFER_READY');
if BufferReadyEvent = 0 then
Exit;
DataReadyEvent := CreateEvent(@SecurityAttributes, False, False, 'DBWIN_DATA_READY');
if DataReadyEvent = 0 then
Exit;
SharedFile := CreateFileMapping(THandle(-1), @SecurityAttributes, PAGE_READWRITE, 0, 4096, 'DBWIN_BUFFER');
if SharedFile = 0 then
Exit;
SharedMem := MapViewOfFile(SharedFile, FILE_MAP_READ, 0, 0, 512);
if not Assigned(SharedMem) then
Exit;
while (not Terminated) and (not Application.Terminated) do
begin
SetEvent(BufferReadyEvent);
WaitingResult := WaitForSingleObject(DataReadyEvent, INFINITE);
case WaitingResult of
WAIT_TIMEOUT: Continue;
WAIT_OBJECT_0:
begin
SharedMessage := String(PAnsiChar(SharedMem) + SizeOf(DWORD));
// here I have what I need and process it in the main thread
end;
WAIT_FAILED: Continue;
end;
end;
UnmapViewOfFile(SharedMem);
CloseHandle(SharedFile);
end;
我添加了C#标签,即使代码在Delphi中,因为安全属性对于整个Windows API和C#有很多追随者:)
I've added C# tag even if the code is in Delphi because the security attributes are common for the whole Windows API and C# has many followers :)
感谢任何建议
推荐答案
有人在 SysInternals论坛中讨论同样的问题。他们的解决方案是将Global\添加到命名对象。
Someone talked about the same issue in the SysInternals forums. Their solution was to add "Global\" to the named objects.
所以使用以下
CreateEvent(@SecurityAttributes, False, True, 'Global\DBWIN_BUFFER_READY');
CreateEvent(@SecurityAttributes, False, False, 'Global\DBWIN_DATA_READY');
CreateFileMapping(THandle(-1), @SecurityAttributes, PAGE_READWRITE, 0, 4096, 'Global\DBWIN_BUFFER');
这篇关于如何从服务中收到OutputDebugString?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!