none
Can a Windows Service do something when a computer "goes to sleep"? RRS feed

  • Question

  • I've tried some functions in service on S3.

    Success : Received NetworkAddressChanged Event  
    Fail :1. get key event(I know it's about security.)
           2. get windows OS version by WMI command
           3. timer
             4. simulate key press by keybd_event
             5. wake up system with SetWaitableTimer

    It seems the service can only receive message and do nothing like file transferring while the system is asleep.
    Thursday, February 13, 2020 7:04 AM

All replies

  • Several questions:

    1. If you want to record your keyboard's actions, Maybe you have to use something like Hook by C++, and call it in the Windows Service.

    2. Try this way instead:

    new ComputerInfo().OSFullName // Library needed using Microsoft.VisualBasic.Devices;

    // Or this way

    public static string get_OSVersion()
    {
        try
        {
            ManagementObject mo = GetMngObj("Win32_OperatingSystem");

            if (null == mo)
                return string.Empty;

            return mo["Version"] as string;
        }
        catch (Exception e)
        {
            return string.Empty;
        }
    }

    3.  For windows service, you can use System.Timers.Timer:

    public partial class Service1 : ServiceBase
        {
            System.Timers.Timer timer1; 
            public Service1()
            {
                InitializeComponent();
            }
     
            protected override void OnStart(string[] args)
            {
               
                timer1 = new System.Timers.Timer();
                timer1.Interval = 3000;  //Interval time here
                timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Elapsed);
                timer1.Enabled = true;
     
                 
     
            }
    
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                 // Do what you want here....
            }
     
            protected override void OnStop()
            {
                //To be executed when stopping the service
                this.timer1.Enabled = false;
            }
     
     
            protected override void OnPause()
            {
                //To be executed when the service is paused
                base.OnPause();
            }
            protected override void OnContinue()
            {
                //To be executed when the service is resumed
                base.OnContinue();
            }
            protected override void OnShutdown()
            {
                //To be executed when the system is closed or the service is crashed
                base.OnShutdown();
            }
        }

    4. You don't need to use the event, because maybe you're using windows service. 

    5. Wake up system, please refer to this sample:

    https://stackoverflow.com/questions/4061844/c-how-to-wake-up-system-which-has-been-shutdown


    Reproduce your quesions with ScreenToGif is your choice. 
    For IIS: IIS Forum
    For WebSite of .NET: ASP.NET Forum
    For others: StackExchange
    For spam-sender or forum urgent issues, Send your Email at:  forumsfeedback@microsoft.com


    Thursday, February 13, 2020 7:38 AM
  • Thank you for your reply.

    Actually some method you mentioned I've tried.

    I should paste my source code  and experimental result in here.

    *nomal : PC is awake

    *- : didn't test

    <style type="text/css"><!--td {border: 1px solid #ccc;}br {mso-data-placement:same-cell;}--></style>
    key event wmi command
    (read windows vesrion)
    windows event
    (NetworkAddressChanged)
    enable key
    (caps lock)
    timer
    normal x v v x v
    S3 (sleep) - x v x x
    S4( hibernate) - - v - -
    modern standby - - v - -


    1.key event

    class globalKeyboardHook {...
       const int WH_KEYBOARD_LL = 13;
       const int WM_KEYDOWN = 0x100;
       const int WM_KEYUP = 0x101;
            ...
       [DllImport("user32.dll")]
       static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);
    
       [DllImport("user32.dll")]
       static extern bool UnhookWindowsHookEx(IntPtr hInstance);
            ...
    
    }
    
    public partial class Service1 : ServiceBase{...
    
       //test key event
       globalKeyboardHook gkh = new globalKeyboardHook();
             ...
       protected override void OnStart(string[] args){ ...
          //test key event
          gkh.HookedKeys.Add(Keys.A);
          gkh.KeyUp += new KeyEventHandler(gkh_KeyUp);
            ...
       void gkh_KeyUp(object sender, KeyEventArgs e)
       {
          eventLog1.WriteEntry("gkh_KeyUp.");
    
          using (StreamWriter outputFile = new 
          StreamWriter(System.IO.Path.Combine(mydocpath, 
          "Log.txt"), true))
          {
             outputFile.WriteLine("gkh_KeyUp.");
          }
          e.Handled = true;
       }
    
    }
    
    
    

    I can't see any log print  when press A

    2&3 . wmi command / Timer

    //test Timer
    Work _WorkObj = new Work(); 
    
    public Service1(){...
     //test Timer
     _WorkObj.StartWorkThread();
            ...
    } 
    
    #region test Timer
    public class Work{
      int count = 0;
      string mydocpath2 = 
      System.AppDomain.CurrentDomain.BaseDirectory;
      private System.Timers.Timer timer = new 
      System.Timers.Timer();
    
      public Work(){
          timer.Enabled = true;
          timer.Interval = 1*1000;  
          timer.Elapsed += new 
          System.Timers.ElapsedEventHandler(timer_Elapsed);
      }
    
      public void StartWorkThread(){
          timer.Start();
      }
      
      private void timer_Elapsed(object sender, 
          System.Timers.ElapsedEventArgs e){
         using (StreamWriter outputFile = new 
         StreamWriter(System.IO.Path.Combine(mydocpath2, 
        "Log.txt"), true)){
                        
         outputFile.WriteLine(DateTime.Now.ToString("yyyy-MM-dd 
         HH:mm:ss ") + "count=" + count++);
         }
      }
    }
    #endregion
    
    
    private void wmi(){
    
       string os_query = "SELECT * FROM Win32_OperatingSystem";
       ManagementObjectSearcher os_searcher =
                    new ManagementObjectSearcher(os_query);
       foreach (ManagementObject info in os_searcher.Get()){
          using (StreamWriter outputFile = new 
              StreamWriter(System.IO.Path.Combine(mydocpath, 
              "ChangeMode.txt"), true)){
             outputFile.WriteLine(
             DateTime.Now.ToString("yyyy-MM- dd HH:mm:ss ")  + 
             "Caption=" + 
             info.Properties["Caption"].Value.ToString().Trim());
           }
    
         }
    }
    
    protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus){
       switch (powerStatus){
          case PowerBroadcastStatus.ResumeSuspend:
             eventLog1.WriteEntry(DateTime.Now.ToString
             ("yyyy-MM-dd HH:mm:ss ") + "S3 Resume.");
          
             using (StreamWriter outputFile = new StreamWriter
             (System.IO.Path.Combine(mydocpath, "Log.txt"), 
             true)){                   
                outputFile.WriteLine
                (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") 
                + "S3 Resume.");
              }
    
             break;
          case PowerBroadcastStatus.Suspend:                 
             eventLog1.WriteEntry(DateTime.Now.ToString
             ("yyyy-MM-dd HH:mm:ss ") + "S3 Suspend.");
             
             using (StreamWriter outputFile = new 
             StreamWriter(System.IO.Path.Combine(mydocpath, 
             "Log.txt"), true)){
                            
             outputFile.WriteLine(DateTime.Now.ToString
             ("yyyy-MM-dd HH:mm:ss ") + "S3 Suspend.");
             }
    
             Thread.Sleep(3000);
             
             //test wmi command
             wmi();
    
             break;
        
          default:
            using (StreamWriter outputFile = new 
            StreamWriter(System.IO.Path.Combine(mydocpath,                 
            "Log.txt"), true)){                  
               
              outputFile.WriteLine(DateTime.Now.ToString
              ("yyyy-MM-dd HH:mm:ss ") + "default=" + 
              powerStatus);
             }
           
            break;
    
                }
         return base.OnPowerEvent(powerStatus);
    }
    
    

    output: timer can't work on S3. OS info. didn't write in txt on S3.

    2020-02-12 15:42:18 count=0
    2020-02-12 15:42:19 count=1
    2020-02-12 15:42:20 count=2
    2020-02-12 15:42:21 count=3
    2020-02-12 15:42:22 S3 Suspend.
    2020-02-12 15:42:22 count=4
    2020-02-12 15:42:23 count=5
    2020-02-12 15:42:48 count=6
    2020-02-12 15:42:48 S3 Resume.
    2020-02-12 15:42:49 default=ResumeAutomatic
    2020-02-12 15:42:49 count=7
    2020-02-12 15:42:49 Caption=Microsoft Windows 10 Enterprise
    2020-02-12 15:42:50 count=8
    2020-02-12 15:42:51 count=9
    2020-02-12 15:42:52 count=10
    2020-02-12 15:42:53 count=11

    5.wake up 

    #region test wake up
    [DllImport("kernel32.dll")]
    public static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SetWaitableTimer(SafeWaitHandle hTimer, [In] ref long pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr lpArgToCompletionRoutine, bool fResume);
    #endregion
     
    public Service1(){
      //test wake up
     SetWaitForWakeUpTime();
    }
    
    static void SetWaitForWakeUpTime()
    {
        DateTime utc = DateTime.Now.AddSeconds(20);
        long duetime = utc.ToFileTime();
    
                using (SafeWaitHandle handle = CreateWaitableTimer(IntPtr.Zero, true, "MyWaitabletimer"))
                {
                    if (SetWaitableTimer(handle, ref duetime, 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());
                    }
                }
    }
    
    

    System can't wake up by this method.

    I didn't make my requirement clear enough.  

    What I want to know is  window service's  ability/ behavior on system asleep.

    maybe like Windows application can't do anything when PC goes to sleep...



    Thursday, February 13, 2020 9:31 AM
  • Hi Yuan Wong,

    Thank you for postign here.

    As far as I know, when the computer is sleeping, the application hangs and does not work properly.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, February 14, 2020 10:01 AM
  • Hello Timon,

    I assume you referred to windows applications, not window services.
    I'm trying to figure out if windows services will also do nothing when system goes to sleep.
    Saturday, February 15, 2020 3:51 AM
  • It depends on what you mean by sleep. If you mean the state that is among the options that include shutdown, logoff, hibernate and restart then the simple answer is that by definition of what sleep means the processor can do no processing. The only way that the processor can do any processing is if it leaves the sleep state. During sleep mode the processor does nothing; depending on the state, the processor might be off. Refer to the following; the last one is about Linux to show that it is an industry standard and/or convention.



    Sam Hobbs
    SimpleSamples.Info


    Saturday, February 15, 2020 9:06 PM