12

मैं (सेवाओं से उन सहित) सभी OutputDebugString संदेशों निम्नलिखित कोड का उपयोग कर पकड़ने की कोशिश कर रहा हूँ। यह ठीक काम किया जब तक मैं विंडोज 7मैं सेवा से आउटपुटडिबगस्ट्रिंग कैसे प्राप्त कर सकता हूं?

समस्या यह है कि जब से Windows Vista सेवाओं में निम्न स्तर सत्र # 0 चल रहे हैं, कुछ लोगों का कहना है कि it's impossible उन्हें पकड़ने की है और कुछ यह है कि करने के लिए चले गए। तुम क्या सोचते हो?

यह कुछ अधिकार में वृद्धि से सत्र # 0 OutputDebugString संदेशों को प्राप्त करने में सक्षम होने के द्वारा निम्नलिखित कोड को संशोधित करना संभव है? दूसरे शब्दों में; सत्र # 1 के साथ सत्र # 0 में DBWIN_BUFFER साझा करना संभव है?

मैं कहूंगा कि यह संभव हो जाना चाहिए क्योंकि जैसे डीबग व्यू ऐसा कर सकता है, और मैं कोई सेवा सहायक नहीं देख सकता जो सत्र # 0 से सत्र # 1 तक उन संदेशों को भेज देगा (जैसे नामित पाइप के माध्यम से), जहां जीयूआई चल रहा है।

समस्या सुरक्षा सेटिंग में IMO हो जाएगा। क्या कोई मुझे सुझाव दे सकता है कि उन्हें कैसे संशोधित किया जाए?

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; 

मैं सी # टैग भले ही कोड डेल्फी में है, क्योंकि सुरक्षा विशेषताओं पूरे Windows API के लिए आम हैं और सी # कई अनुयायियों :)

उत्तर

11

किसी एक ही बारे में बात की है जोड़ दिया है SysInternals forums में समस्या। उनका समाधान 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'); 
+1

+1 का उपयोग करें और स्वीकार करते हैं। धन्यवाद; अच्छी तरह से काम। मैं क्षमा के साथ आपके उत्तर में विशिष्ट समाधान जोड़ दूंगा। –