Midas Midas - 2 months ago 47
C# Question

SystemEvents.PowerModeChanged event handler not being called in VSTO & WPF apps

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.

Answer

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