原因是软件要做一个日志窗体
跨进程的
本人想假如c#能获取OutputDebugString消息 来显示 那么太完美了
求各位大神解惑
假如用c#来获取OutputDebugString的消息
程序为debug版本
跨进程的
本人想假如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; }