3

I am developing a VSTO application-level Word AddIn and a WPF application, both need to be notified when the system goes to sleep and subsequently resumes. I have bound my event handlers to the SystemEvents.PowerModeChanged event in each application, but for some reason it still never gets called when the system goes to sleep or resumes. Just to test, I am simply trying to write to the console when the system goes to sleep. I also tried setting breakpoints, but that didn't work either; although I'm not sure if they would've anyway, given that the system is suspending applications. With either attempt, it never prints nor breaks:

VSTO Addin

void ThisAddIn_Startup(object sender, EventArgs e)
{
  SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(powerModeChanged);
}

public void powerModeChanged(object sender, PowerModeChangedEventArgs args)
{
  Console.WriteLine("Sleeping.....");
}

WPF

internal MyControl()
{
    SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(powerModeChanged);
}

 public void powerModeChanged(object sender, PowerModeChangedEventArgs args)
 {
     Console.WriteLine("Sleeping!!");
 }

I have tried changing the access level of the event handlers from public to private to internal and vice-versa as well as moving the binding to other parts of the code in each application, but it didn't solve the issue. Any help would be greatly appreciated thank you!


SOLUTION: As per the comments and helpful answer, the event wasn't firing because I was running windows through a VirtualBox VM. Once my coworker ran the code on a native windows machine, it worked.

jsanalytics
  • 13,058
  • 4
  • 22
  • 43
mattyb
  • 1,011
  • 2
  • 10
  • 26
  • This is most likely caused, because you dont have an `Console` in VSTO. Try to write into a `File` instead of Console to ensure your Event gets fired. – lokusking Sep 12 '16 at 06:14
  • @lokusking just tried that and it didn't work, I guess that means my EventHandler isn't being bound to the event correctly? – mattyb Sep 15 '16 at 18:38
  • Also, I'm running this on a VirtualBox Windows 10 VM instance, not sure if that could be an issue? – mattyb Sep 15 '16 at 19:51
  • Another option is found [here](http://stackoverflow.com/questions/6799955/how-to-detect-windows-shutdown-or-logoff). Tbh, i dont know if this handles the Suspension aswell – lokusking Sep 15 '16 at 20:08
  • Using Console.WriteLine() in a library that is used in apps that don't have a console is not productive, you can of course never see it. Another classic hangup is that the machine's power mode changed before .NET had an opportunity to call your event handler. You'll get the event twice when the machine is powered up again :) Using it in a VM, just don't bother. – Hans Passant Sep 15 '16 at 22:21
  • Yeah the VM messed this up, just had my coworker run this code on an actual windows laptop and it worked! – mattyb Sep 16 '16 at 01:26

1 Answers1

1

Try this:

XAML:

<Window x:Class="WpfApplication279.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication279"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid>
    <ListView x:Name="listView1" Margin="0">
        <ListView.View>
            <GridView>
                <GridViewColumn/>
            </GridView>
        </ListView.View>
    </ListView>

</Grid>

MainWindow:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
    }

    private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
    {
        listView1.Items.Add(string.Format("{0} : Power mode changed = {1}", DateTime.Now, e.Mode));
    }
}

enter image description here


In order to trigger the event in a Windows 10 machine, right-click the Start button and then:

enter image description here


Letting the machine go into sleep mode by timeout works the same way. These are my settings:

enter image description here

Same result:

enter image description here

jsanalytics
  • 13,058
  • 4
  • 22
  • 43
  • Sorry for the delay, just tried implementing this using your exact code and unfortunately nothing ever showed up in the listView. Is there a setting in Visual Studio or some solution/project-wide property i haven't set that is preventing my event handler from being called? Thanks for the help! – mattyb Sep 15 '16 at 19:42
  • Also, I'm running this on a VirtualBox Windows 10 VM instance, not sure if that could be an issue? – mattyb Sep 15 '16 at 19:51
  • How do you make your VM instance go into sleep mode? – jsanalytics Sep 15 '16 at 20:33
  • To your first comment, i set the sleep threshold to 1 minute so it was sleeping quickly. I will try your edit although it was going to sleep on my VM because I set the sleep threshold to be so low. – mattyb Sep 15 '16 at 20:55
  • I set my threshold to 1 minute as well and it works same way. – jsanalytics Sep 15 '16 at 21:38
  • Is your VM or your host machine that is going into sleep mode? – jsanalytics Sep 15 '16 at 21:40
  • Should we go in a chat? But it is my VM, im going to try your method of manually pressing sleep from the control panel. – mattyb Sep 15 '16 at 21:41
  • Just had my coworker run this code on an actual windows laptop and it worked! For some reason my VM doesn't register this event! – mattyb Sep 16 '16 at 01:26