첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.

728x90
반응형
728x170

TestProject.zip
다운로드

▶ WakeUpHelper.cs

using Microsoft.Win32.SafeHandles;
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Threading;

namespace TestProject
{
    /// <summary>
    /// 절전 모드 기상 헬퍼
    /// </summary>
    public class WakeUpHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Import
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 대기 가능한 타이머 생성하기 - CreateWaitableTimer(timerAttributeHandle, manualReset, timerName)

        /// <summary>
        /// 대기 가능한 타이머 생성하기
        /// </summary>
        /// <param name="timerAttributeHandle">타이머 어트리뷰트 핸들</param>
        /// <param name="manualReset">수동 리셋 여부</param>
        /// <param name="timerName">타이머명</param>
        /// <returns>타이머 핸들</returns>
        [DllImport("kernel32.dll")]
        private static extern SafeWaitHandle CreateWaitableTimer(IntPtr timerAttributeHandle, bool manualReset, string timerName);

        #endregion
        #region 대기 가능한 타이머 설정하기 - SetWaitableTimer(timerHandle, dueTime, period,
            completionRoutineHandle, argumentHandleToCompletionRoutine, resume)

        /// <summary>
        /// 대기 가능한 타이머 설정하기
        /// </summary>
        /// <param name="timerHandle">타이머 핸들</param>
        /// <param name="dueTime">타이머 신호 수신 시간 (단위 : 100 나노초)</param>
        /// <param name="period">타이머 기간 (단위 : 밀리초)</param>
        /// <param name="completionRoutineHandle">완료 루틴 핸들</param>
        /// <param name="argumentHandleToCompletionRoutine">완료 루틴용 인자 핸들</param>
        /// <param name="resume">복원 여부</param>
        /// <returns>처리 결과</returns>
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetWaitableTimer
        (
            SafeWaitHandle timerHandle,
            [In] ref long  dueTime,
            int            period,
            IntPtr         completionRoutineHandle,
            IntPtr         argumentHandleToCompletionRoutine,
            bool           resume
        );

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Event
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 기상시 이벤트 - Woken

        /// <summary>
        /// 기상시 이벤트
        /// </summary>
        public event EventHandler Woken;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 백그라운드 작업자
        /// </summary>
        private BackgroundWorker backgroundWorker = new BackgroundWorker();

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - WakeUpHelper()

        /// <summary>
        /// 생성자
        /// </summary>
        public WakeUpHelper()
        {
            this.backgroundWorker.DoWork             += backgroundWorker_DoWork;
            this.backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public
        //////////////////////////////////////////////////////////////////////////////// Function

        #region 기상 시간 설정하기 - SetWakeUpTime(dateTime)

        /// <summary>
        /// 기상 시간 설정하기
        /// </summary>
        /// <param name="dateTime">날짜/시간</param>
        public void SetWakeUpTime(DateTime dateTime)
        {
            this.backgroundWorker.RunWorkerAsync(dateTime.ToFileTime());
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 백그라운드 작업자 작업 완료시 처리하기 - backgroundWorker_RunWorkerCompleted(sender, e)

        /// <summary>
        /// 백그라운드 작업자 작업 완료시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Woken?.Invoke(this, EventArgs.Empty);
        }

        #endregion
        #region 백그라운드 작업자 작업시 처리하기 - backgroundWorker_DoWork(sender, e) 

        /// <summary>
        /// 백그라운드 작업자 작업시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
        {
            long wakeUpTime = (long)e.Argument;

            string timerName = GetType().Assembly.GetName().Name.ToString() + "Timer";

            using(SafeWaitHandle timerHandle = CreateWaitableTimer(IntPtr.Zero, true, timerName))
            {
                if(SetWaitableTimer(timerHandle, ref wakeUpTime, 0, IntPtr.Zero, IntPtr.Zero, true))
                {
                    using(EventWaitHandle waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset))
                    {
                        waitHandle.SafeWaitHandle = timerHandle;

                        waitHandle.WaitOne();
                    }
                }
                else
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
        }

        #endregion
    }
}

 

728x90

 

▶ MainForm.cs

using System;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            this.timer.Tick           += timer_Tick;
            this.setTimerButton.Click += setTimerButton_Click;
            this.suspendButton.Click  += suspendButton_Click;

            this.timer.Start();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 타이머 틱 처리하기 - timer_Tick(sender, e)

        /// <summary>
        /// 타이머 틱 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void timer_Tick(object sender, EventArgs e)
        {
            this.currentTimeLabel.Text = string.Format("현재 시간 : {0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

            this.currentTimeLabel.Update();
        }

        #endregion
        #region 절전 모드 기상 헬퍼 기상시 처리하기 - wakeUpHelper_Woken(sender, e)

        /// <summary>
        /// 절전 모드 기상 헬퍼 기상시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void wakeUpHelper_Woken(object sender, EventArgs e)
        {
            wokenTimeLabel.Text = string.Format("기상 시간 : {0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
        }

        #endregion
        #region 타이머 설정 버튼 클릭시 처리하기 - setTimerButton_Click(sender, e)

        /// <summary>
        /// 타이머 설정 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void setTimerButton_Click(object sender, EventArgs e)
        {
            WakeUpHelper wakeUpHelper = new WakeUpHelper();

            wakeUpHelper.Woken += wakeUpHelper_Woken;

            wakeUpHelper.SetWakeUpTime(this.setupTimeDateTimePicker.Value);
        }

        #endregion
        #region 절전 모드 설정 버튼 클릭시 처리하기 - suspendButton_Click(sender, e)

        /// <summary>
        /// 절전 모드 설정 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void suspendButton_Click(object sender, EventArgs e)
        {
            Application.SetSuspendState(PowerState.Suspend, false, false);
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요