public static extern SafeWaitHandle CreateWaitableTimer( SECURITY_ATTRIBUTES timerAttributes, bool manualReset, string timerName);
public static extern SafeWaitHandle CreateWaitableTimerEx( SECURITY_ATTRIBUTES timerAttributes, string timerName, Int32 flags, UInt32 desiredAccess);
private unsafe SafeWaitHandle CreateTimerHandle(bool manualReset, string name, out bool createdNew, WaitableTimerSecurity timerSecurity) { if (name != null && name.Length > 260) { throw new ArgumentException("name is too long."); } SECURITY_ATTRIBUTES secattr = null; if (timerSecurity != null) { // Create a SECURITY_ATTRIBUTES class and populate it // from the information stored in timerSecurity secattr = new SECURITY_ATTRIBUTES(); secattr.nLength = Marshal.SizeOf(secattr); byte[] binaryForm = timerSecurity.GetSecurityDescriptorBinaryForm(); byte* pbin = stackalloc byte[binaryForm.Length]; fixed (byte* psrc = binaryForm) { for (int i = 0; i < binaryForm.Length; ++i) { *(pbin + i) = *(psrc + i); } } secattr.lpSecurityDescriptor = (IntPtr)pbin; } SafeWaitHandle handle = Win32WaitableTimer.CreateWaitableTimer(secattr, manualReset, name); int lastError = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { if (name == null) { throw GetWin32Exception(); } if (lastError == Win32WaitableTimer.ERROR_INVALID_HANDLE) { throw new WaitHandleCannotBeOpenedException("Invalid handle"); } throw new WaitHandleCannotBeOpenedException(); } createdNew = (Marshal.GetLastWin32Error() == Win32WaitableTimer.ERROR_ALREADY_EXISTS); return handle; }