-2

I wrote a Winforms app that alarms for certain events by playing sounds using the WMPLib.WindowsMediaPlayer. But the issue is, when the system is sleeping, it doesn't play anything.

As soon as I press some buttons on the keyboard where you see the windows fingerprint/PIN screen, the sound starts playing, if an alarm event is active.

How can I make it so that it plays the sounds regardless of the system sleeping state.

Do I have to wake the computer in code in such cases? If so, how?

Joan Venge
  • 315,713
  • 212
  • 479
  • 689
  • 1
    If a system plays sound when it's sleeping then it's no more sleeping. – Reza Aghaei Feb 06 '21 at 20:32
  • The only way to stop this is to disable sleep mode. By definition if your computer goes to sleep then windows will stop your programs from running! see here: https://www.wikihow.com/Prevent-Windows-10-from-Going-to-Sleep – Ocean Airdrop Feb 06 '21 at 20:36
  • 2
    In addition to OS and hardware, the software also should support [Modern Standby](https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby?WT.mc_id=DT-MVP-5003235) to be able to keep playing sound on modern standby. Have you checked to see whether the Windows Media Player supports modern standby? Open WMP, play a music and let it go to standby, if it continues playing it means WMP (and WMP active-x) supports modern standby, otherwise it means WMP (and WMP active-x) doesn't support modern standby. – Reza Aghaei Feb 06 '21 at 20:49
  • 1
    @RezaAghaei I will check this – Joan Venge Feb 07 '21 at 07:40

2 Answers2

1

I'm unsure, but it looks like you can create a timer, which will wake up the system in desired moment. Then you will able to play your sound as usual. The idea is a following:

  • create a waitable timer with CreateWaitableTimerW
  • set the timer to a desired time with SetWaitableTimer, passing fResume=TRUE
  • wait for the timer with WaitForSingleObject
  • play your sound as usual.
Serg
  • 3,454
  • 2
  • 13
  • 17
1

You can use the SetThreadExecutionState function.

SetThreadExecutionState. Enables an application to inform the system that it is in use, thereby preventing the system from entering sleep or turning off the display while the application is running.

  • Display is OFF but the system is active.
SetThreadExecutionState(ExecutionState.ES_CONTINUOUS | ExecutionState.ES_AWAYMODE_REQUIRED );
  • Display is allways ON
SetThreadExecutionState(ExecutionState.ES_CONTINUOUS | ExecutionState.ES_AWAYMODE_REQUIRED | ExecutionState.ES_DISPLAY_REQUIRED);

In this example every 30 seconds, the program calls SetThreadExecutionState function.

You can check/download this code on https://github.com/JomaStackOverflowAnswers/PreventWmplayerStopWhenSleep

Code


using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace PreventSleep
{
    public partial class FrmMain : Form
    {
        const int REFRESH_MILLISECONDS = 30000;//Change this value. 30000ms = 30s.

        [Flags]
        public enum ExecutionState : uint 
        {
            ES_AWAYMODE_REQUIRED = 0x00000040,
            ES_CONTINUOUS = 0x80000000,
            ES_DISPLAY_REQUIRED = 0x00000002,
            ES_SYSTEM_REQUIRED = 0x00000001
        }

        
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
        static extern ExecutionState SetThreadExecutionState(ExecutionState esFlags);



        Stopwatch stopwatch;
        private Timer timerRefresh;

        public FrmMain()
        {
            InitializeComponent();
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            stopwatch = new Stopwatch();
            stopwatch.Start();
            axWindowsMediaPlayer1.URL = Directory.GetCurrentDirectory() + "\\Music.mp3";
            axWindowsMediaPlayer1.settings.setMode("loop", true);
            axWindowsMediaPlayer1.Ctlcontrols.play();
            axWindowsMediaPlayer1.uiMode = "none";

            timerRefresh = new Timer();
            timerRefresh.Enabled = true;
            timerRefresh.Interval = 1000;
            timerRefresh.Tick += new EventHandler(this.timerRefresh_Tick);
        }

        private void timerRefresh_Tick(object sender, EventArgs e)
        {
            if((stopwatch.ElapsedMilliseconds / REFRESH_MILLISECONDS) == 1 )
            {
                stopwatch.Restart();
                SetThreadExecutionState(ExecutionState.ES_CONTINUOUS | ExecutionState.ES_AWAYMODE_REQUIRED ); //Display is OFF but the system is active.
                //SetThreadExecutionState(ExecutionState.ES_CONTINUOUS | ExecutionState.ES_AWAYMODE_REQUIRED | ExecutionState.ES_DISPLAY_REQUIRED); //Display is allways ON.
            }
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            stopwatch.Stop();
            axWindowsMediaPlayer1.Ctlcontrols.stop();
            SetThreadExecutionState(ExecutionState.ES_CONTINUOUS);
        }
    }
}

My Settings enter image description here

Joma
  • 3,520
  • 1
  • 29
  • 32