一个小问题 OutputDebugString 用c#来获取这些消息

.Net技术 码拜 9年前 (2016-01-29) 1890次浏览
原因是软件要做一个日志窗体
跨进程的
本人想假如c#能获取OutputDebugString消息 来显示  那么太完美了
求各位大神解惑
假如用c#来获取OutputDebugString的消息
程序为debug版本
解决方案:20分
高手们都放假happy去啦。友情帮顶
解决方案:180分
原理请参考http://www.codeproject.com/Articles/23776/Mechanism-of-OutputDebugString。

class Test
{
    static void Main(string[] args)
    {
        using (DbgView dbgView = new DbgView(Console.Out))
        {
            dbgView.Start();
            Console.ReadLine();
        }
    }
}
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Threading;
public class DbgView : IDisposable
{
    public DbgView(TextWriter writer)
    {
        if (writer == null) throw new ArgumentNullException("writer");
        this.writer = writer;
    }
    public void Start()
    {
        lock (this.lockObj)
        {
            if (this.listenerThread == null)
            {
                this.listenerThread = new Thread(ListenerThread) { IsBackground = true };
                this.listenerThread.Start();
            }
        }
    }
    public void Stop()
    {
        lock (this.lockObj)
        {
            if (this.listenerThread != null)
            {
                this.listenerThread.Interrupt();
                this.listenerThread.Join(10 * 1000);
                this.listenerThread = null;
            }
        }
    }
    public void Dispose()
    {
        this.Stop();
    }
    private void ListenerThread(object state)
    {
        EventWaitHandle bufferReadyEvent = null;
        EventWaitHandle dataReadyEvent = null;
        MemoryMappedFile memoryMappedFile = null;
        try
        {
            bool createdNew;
            var everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
            var eventSecurity = new EventWaitHandleSecurity();
            eventSecurity.AddAccessRule(new EventWaitHandleAccessRule(everyone, EventWaitHandleRights.Modify | EventWaitHandleRights.Synchronize, AccessControlType.Allow));
            bufferReadyEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "DBWIN_BUFFER_READY", out createdNew, eventSecurity);
            if (!createdNew) throw new Exception("Some DbgView already running");
            dataReadyEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "DBWIN_DATA_READY", out createdNew, eventSecurity);
            if (!createdNew) throw new Exception("Some DbgView already running");
            var memoryMapSecurity = new MemoryMappedFileSecurity();
            memoryMapSecurity.AddAccessRule(new AccessRule<MemoryMappedFileRights>(everyone, MemoryMappedFileRights.ReadWrite, AccessControlType.Allow));
            memoryMappedFile = MemoryMappedFile.CreateNew("DBWIN_BUFFER", 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, memoryMapSecurity, System.IO.HandleInheritability.None);
            bufferReadyEvent.Set();
            this.writer.WriteLine("[DbgView] Started.");
            using (var accessor = memoryMappedFile.CreateViewAccessor())
            {
                byte[] buffer = new byte[4096];
                while (dataReadyEvent.WaitOne())
                {
                    accessor.ReadArray<byte>(0, buffer, 0, buffer.Length);
                    int processId = BitConverter.ToInt32(buffer, 0);
                    int terminator = Array.IndexOf<byte>(buffer, 0, 4);
                    string msg = Encoding.Default.GetString(buffer, 4, (terminator < 0 ? buffer.Length : terminator) - 4);
                    writer.Write("[{0:00000}] {1}", processId, msg);
                    bufferReadyEvent.Set();
                }
            }
        }
        catch (ThreadInterruptedException)
        {
            this.writer.WriteLine("[DbgView] Stopped.");
        }
        catch (Exception e)
        {
            this.writer.WriteLine("[DbgView] Error: " + e.Message);
        }
        finally
        {
            foreach (var disposable in new IDisposable[] { bufferReadyEvent, dataReadyEvent, memoryMappedFile })
            {
                if (disposable != null) disposable.Dispose();
            }
        }
    }
    private Thread listenerThread;
    private readonly object lockObj = new object();
    private readonly TextWriter writer;
}

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明一个小问题 OutputDebugString 用c#来获取这些消息
喜欢 (0)
[1034331897@qq.com]
分享 (0)