jellyfin-server/MediaBrowser.ServerApplication/Native/WindowsPowerManagement.cs

94 lines
3.3 KiB
C#
Raw Normal View History

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Threading;
using MediaBrowser.Controller.Power;
2016-01-21 17:45:42 +00:00
using MediaBrowser.Model.Logging;
using Microsoft.Win32.SafeHandles;
namespace MediaBrowser.ServerApplication.Native
{
public class WindowsPowerManagement : IPowerManagement
{
[DllImport("kernel32.dll")]
2016-01-21 17:45:42 +00:00
public static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes,
bool bManualReset,
string lpTimerName);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
2016-01-21 17:45:42 +00:00
public static extern bool SetWaitableTimer(SafeWaitHandle hTimer,
[In] ref long pDueTime,
int lPeriod,
IntPtr pfnCompletionRoutine,
IntPtr lpArgToCompletionRoutine,
bool fResume);
private BackgroundWorker _bgWorker;
private readonly ILogger _logger;
private readonly object _initLock = new object();
public WindowsPowerManagement(ILogger logger)
{
_logger = logger;
}
public void ScheduleWake(DateTime utcTime)
{
2016-01-21 17:45:42 +00:00
Initialize();
_bgWorker.RunWorkerAsync(utcTime.ToFileTime());
}
2016-01-21 17:45:42 +00:00
private void Initialize()
{
lock (_initLock)
{
2016-01-21 17:45:42 +00:00
if (_bgWorker == null)
{
2016-01-21 17:45:42 +00:00
_bgWorker = new BackgroundWorker();
_bgWorker.DoWork += bgWorker_DoWork;
_bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted;
}
2016-01-21 17:45:42 +00:00
}
}
void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//if (Woken != null)
//{
// Woken(this, new EventArgs());
//}
}
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
long waketime = (long)e.Argument;
using (SafeWaitHandle handle = CreateWaitableTimer(IntPtr.Zero, true, GetType().Assembly.GetName().Name + "Timer"))
{
2016-01-21 17:45:42 +00:00
if (SetWaitableTimer(handle, ref waketime, 0, IntPtr.Zero, IntPtr.Zero, true))
{
using (EventWaitHandle wh = new EventWaitHandle(false,
EventResetMode.AutoReset))
{
wh.SafeWaitHandle = handle;
wh.WaitOne();
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}
2016-01-21 17:45:42 +00:00
catch (Exception ex)
{
_logger.ErrorException("Error scheduling wake timer", ex);
}
}
}
}