/// <summary> /// Starts a new trace log file with the given session name writing it to the specified file. /// /// If a session name is not provided a unique name will be generated /// </summary> /// <param name="sessionName"></param> /// <param name="filename"></param> /// <returns></returns> public static TraceLog Start(string filename, string sessionName = null) { if (sessionName == null) { sessionName = Guid.NewGuid().ToString(); } var bufferSize = Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES)) + (sessionName.Length + 1) * 2 + (filename.Length + 1) * 2; var mem = Marshal.AllocHGlobal(bufferSize); for (int i = 0; i < bufferSize; i++) { Marshal.WriteByte(mem, i, 0); } if (mem == IntPtr.Zero) { throw new OutOfMemoryException(); } EVENT_TRACE_PROPERTIES eventProps = new EVENT_TRACE_PROPERTIES(); eventProps.Wnode.BufferSize = (uint)bufferSize; eventProps.BufferSize = 512; eventProps.Wnode.Guid = Guid.NewGuid(); eventProps.LogFileMode = EVENT_TRACE_PRIVATE_IN_PROC | EVENT_TRACE_PRIVATE_LOGGER_MODE | EVENT_TRACE_FILE_MODE_SEQUENTIAL; eventProps.MaximumFileSize = 0; eventProps.Wnode.Flags = EtlNativeMethods.WNODE_FLAG_TRACED_GUID; eventProps.Wnode.TimeStamp = 0; eventProps.Wnode.ClientContext = 0; eventProps.LoggerNameOffset = (uint)Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES)); eventProps.LogFileNameOffset = (uint)(Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES)) + (sessionName.Length + 1) * 2); Marshal.StructureToPtr(eventProps, mem, false); int offset = (int)eventProps.LogFileNameOffset; for (int i = 0; i < filename.Length; i++, offset += 2) { Marshal.WriteInt16(mem, offset, filename[i]); } Marshal.WriteInt16(mem, offset, 0); bool success = false; try { ulong handle; var error = EtlNativeMethods.StartTraceW( out handle, sessionName, mem ); if (error != 0) { throw new Win32Exception((int)error); } var res = new TraceLog(handle, sessionName, mem); success = true; return res; } finally { if (!success) { Marshal.FreeHGlobal(mem); } } }
/// <summary> /// Starts a new trace log file with the given session name writing it to the specified file. /// /// If a session name is not provided a unique name will be generated /// </summary> /// <param name="sessionName"></param> /// <param name="filename"></param> /// <returns></returns> public static TraceLog Start(string filename, string sessionName = null) { if (sessionName == null) { sessionName = Guid.NewGuid().ToString(); } var bufferSize = Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES)) + (sessionName.Length + 1) * 2 + (filename.Length + 1) * 2; var mem = Marshal.AllocHGlobal(bufferSize); for (int i = 0; i < bufferSize; i++) { Marshal.WriteByte(mem, i, 0); } if (mem == IntPtr.Zero) { throw new OutOfMemoryException(); } EVENT_TRACE_PROPERTIES eventProps = new EVENT_TRACE_PROPERTIES(); eventProps.Wnode.BufferSize = (uint)bufferSize; eventProps.BufferSize = 512; eventProps.Wnode.Guid = Guid.NewGuid(); eventProps.LogFileMode = EVENT_TRACE_PRIVATE_IN_PROC | EVENT_TRACE_PRIVATE_LOGGER_MODE | EVENT_TRACE_FILE_MODE_SEQUENTIAL; eventProps.MaximumFileSize = 0; eventProps.Wnode.Flags = EtlNativeMethods.WNODE_FLAG_TRACED_GUID; eventProps.Wnode.TimeStamp = 0; eventProps.Wnode.ClientContext = 0; eventProps.LoggerNameOffset = (uint)Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES)); eventProps.LogFileNameOffset = (uint)(Marshal.SizeOf(typeof(EVENT_TRACE_PROPERTIES)) + (sessionName.Length + 1) * 2); Marshal.StructureToPtr(eventProps, mem, false); int offset = (int)eventProps.LogFileNameOffset; for (int i = 0; i < filename.Length; i++, offset += 2) { Marshal.WriteInt16(mem, offset, filename[i]); } Marshal.WriteInt16(mem, offset, 0); bool success = false; try { ulong handle; var error = EtlNativeMethods.StartTraceW( out handle, sessionName, mem ); if (error != 0) { throw new Win32Exception((int)error); } var res = new TraceLog(handle, sessionName, mem); success = true; return(res); } finally { if (!success) { Marshal.FreeHGlobal(mem); } } }