How to prevent Windows from entering idle state? - c#

I am working on a C# application which runs in the background without any Windows control.
I want to notify Windows that my application is still alive to prevent Windows from going into the idle state.
Are there any APIs available to call from my application which notify the Windows OS that my application is still alive?
Thanks in advance.

You've to use SetThreadExecutionState function. Something like this:
public partial class MyWinForm: Window
{
private uint fPreviousExecutionState;
public Window1()
{
InitializeComponent();
// Set new state to prevent system sleep
fPreviousExecutionState = NativeMethods.SetThreadExecutionState(
NativeMethods.ES_CONTINUOUS | NativeMethods.ES_SYSTEM_REQUIRED);
if (fPreviousExecutionState == 0)
{
Console.WriteLine("SetThreadExecutionState failed. Do something here...");
Close();
}
}
protected override void OnClosed(System.EventArgs e)
{
base.OnClosed(e);
// Restore previous state
if (NativeMethods.SetThreadExecutionState(fPreviousExecutionState) == 0)
{
// No way to recover; already exiting
}
}
}
internal static class NativeMethods
{
// Import SetThreadExecutionState Win32 API and necessary flags
[DllImport("kernel32.dll")]
public static extern uint SetThreadExecutionState(uint esFlags);
public const uint ES_CONTINUOUS = 0x80000000;
public const uint ES_SYSTEM_REQUIRED = 0x00000001;
}

You have a couple of options:
Use SetThreadExecutionState, which:
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.
Where you could use the ES_SYSTEM_REQUIRED flag to
Forces the system to be in the working state by resetting the system idle timer.
Use SendInput to fake keystroke, mouse motion/clicks
Another alternative would be to change your app to be a Windows service.
SetThreadExecutionState example
// Television recording is beginning. Enable away mode and prevent
// the sleep idle time-out.
SetThreadExecutionState(
ES_CONTINUOUS |
ES_SYSTEM_REQUIRED |
ES_AWAYMODE_REQUIRED);
// Wait until recording is complete...
// Clear EXECUTION_STATE flags to disable away mode and allow the system
// to idle to sleep normally.
SetThreadExecutionState(ES_CONTINUOUS);

You can use SetThreadExecutionState described here:
SetThreadExecutionState Function
Since it is a Win32 API function, to use it from C# you'll need to PInvoke it. The steps are described here, including a sample method PreventSleep to temporarily disable sleep mode:
PInvoke.net: setthreadexecutionstate (kernel32)

I don't think there's any way to do this directly in managed code.
A quick search reveals this post from 2 years ago. Basically you'd need to do some interop to call a raw windows API.

Here is SetThreadExecutionState C# implementation

Related

How to interrupt Screen-saver under windows 8

I would like know how to interrupt Screen-saver under the Windows 8(Embedded version) or Windows 10, Because a window(C#) of my project only run under the normal status, otherwise it will be error if run under Screen-saver. so I want to interrupt the Screen-saver before this window pop-up.
I have researched some solution and idea that included as below,
a. Move mouse(used the user32's mouse_event api)
b. Send keys(also used the user32's api)
c. Kill screen-saver process.
Both of a & b are ways I have tried them and worked well on the windows 10, but not worked on the Windows 8(Embedded version), so currently I only focus on the c way, about way of c I searched the as below link,
https://support.microsoft.com/en-us/help/140723/how-to-force-a-screen-saver-to-close-once-started-in-windows-nt,-windows-2000,-and-windows-server-2003
https://www.codeproject.com/Articles/17067/Controlling-The-Screen-Saver-With-C
but above links still aren't work on the windows 10 and Windows 8(Embedded version), which expert give me some suggestion? thanks in advance.
Have a look at the unmanaged API functions GetSystemPowerStatus and SetThreadExecutionState. Using a (thread) timer, you can periodically update the status, e.g. from a class property, and inform the system about your requirements. This is useful, if your application may allow or disallow the screensaver, depending on it's operating state.
public class PowerManager : IDisposable
{
[Flags]
public enum ExecutionStateEnum : uint
{
LetTheSystemDecide = 0x00,
SystemRequired = 0x01,
SystemDisplayRequired = 0x02,
UserPresent = 0x04,
Continuous = 0x80000000,
}
[DllImport("kernel32")]
private static extern uint SetThreadExecutionState(ExecutionStateEnum esFlags);
public PowerManager() {}
public Update(ExecutionStateEnum state)
{
SetThreadExecutionState(state);
}
}
Update:
Then call PowerManager.Update(ExecutionStateEnum.SystemDisplayRequired) to disable the screensaver or call PowerManager.Update(ExecutionStateEnum.LetTheSystemDecide) to restore the default system behaviour (allow the screensaver).
If the method is called periodically from a timer callback, adjust the timer interval according to the configured screensaver timeout.

Why does closing a console that was started with AllocConsole cause my whole application to exit? Can I change this behavior?

What I want to have happen is that the console window just goes away, or better yet that it is hidden, but I want my application to keep running. Is that possible? I want to be able to use Console.WriteLine and have the console serve as an output window. I want to be able to hide and show it, and I don't want the whole app to die just because the console was closed.
EDIT
Code:
internal class SomeClass {
[DllImport("kernel32")]
private static extern bool AllocConsole();
private static void Main() {
AllocConsole();
while(true) continue;
}
}
EDIT 2
I tried the accepted solution here [ Capture console exit C# ], per the suggestion in the comments on this question. The example code is bugged in that the DLLImport needs to be "kernel32.dll" or "kernel32", not "Kernel32". After making that change, I'm getting a message to my handler for CTRL_CLOSE_EVENT when I click the X on the console window. However, calling FreeConsole and/or returning true doesn't prevent the application from terminating.
Ah, yes, this is one of the caveats of using the Windows console subsystem. When the user closes the console window (regardless of how the console was allocated), all of the processes that are attached to the console are terminated. That behavior makes obvious sense for console applications (i.e., those that specifically target the console subsystem, as opposed to standard Windows applications), but it can be a major pain in cases like yours.
The only workaround that I know of is to use the SetConsoleCtrlHandler function, which allows you to register a handler function for Ctrl+C and Ctrl+Break signals, as well as system events like the user closing the console window, the user logging off, or the system shutting down. The documentation says that if you're only interested in ignoring these events, you can pass null for the first argument. For example:
[DllImport("kernel32")]
static extern bool SetConsoleCtrlHandler(HandlerRoutine HandlerRoutine, bool Add);
delegate bool HandlerRoutine(uint dwControlType);
static void Main()
{
AllocConsole();
SetConsoleCtrlHandler(null, true);
while (true) continue;
}
That works perfectly for Ctrl+C and Ctrl+Break signals (which would have otherwise caused your application to terminate as well), but it doesn't work for the one you're asking about, which is the CTRL_CLOSE_EVENT, generated by the system when the user closes the console window.
Honestly, I don't know how to prevent that. Even the sample in the SDK doesn't actually allow you to ignore the CTRL_CLOSE_EVENT. I tried it in a little test app, and it beeps when you close the window and prints the message, but the process still gets terminated.
Perhaps more worryingly, the documentation makes me think it is not possible to prevent this:
The system generates CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals when the user closes the console, logs off, or shuts down the system so that the process has an opportunity to clean up before termination. Console functions, or any C run-time functions that call console functions, may not work reliably during processing of any of the three signals mentioned previously. The reason is that some or all of the internal console cleanup routines may have been called before executing the process signal handler.
It's that last sentence that catches my eye. If the console subsystem starts cleaning up after itself immediately in response to the user attempting to close the window, it may not be possible to halt it after the fact.
(At least now you understand the problem. Maybe someone else can come along with a solution!)
Unfortunately there's nothing you can do to really alter this behaviour.
Console windows are "special" in that they're hosted by another process and do not allow sub-classing. This limits your ability to modify their behaviour.
From what I know, your two options are:
1. Disable the close button altogether. You can do this with the following code fragment:
HWND hwnd = ::GetConsoleWindow();
if (hwnd != NULL)
{
HMENU hMenu = ::GetSystemMenu(hwnd, FALSE);
if (hMenu != NULL) DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
}
2. Stop using consoles altogether, and implement your own text output solution.
Option #2 is the more complicated option but would provide you the greatest control. I found an article on CodeProject that implements a console-like application using a rich edit control to display the text (rich edit controls have the ability to stream text like the console, so they are well suited to this sort of application).
On closing the console window obtained using AllocConsole or AttachConsole, the associated process will exit. There is no escape from that.
Prior to Windows Vista, closing the console window would present a confirmation dialogue to the user asking him whether the process should be terminated or not but Windows Vista and later do not provide any such dialogue and the process gets terminated.
One possible solution to work around this is avoiding AttachConsole altogether and achieving the desired functionality through other means.
For instance in the case described by OP, console window was needed to output some text on Console using Console static class.
This can be achieved very easily using inter-process communication. For example a console application can be developed to act as an echo server
namespace EchoServer
{
public class PipeServer
{
public static void Main()
{
var pipeServer = new NamedPipeServerStream(#"Com.MyDomain.EchoServer.PipeServer", PipeDirection.In);
pipeServer.WaitForConnection();
StreamReader reader = new StreamReader(pipeServer);
try
{
int i = 0;
while (i >= 0)
{
i = reader.Read();
if (i >= 0)
{
Console.Write(Convert.ToChar(i));
}
}
}
catch (IOException)
{
//error handling code here
}
finally
{
pipeServer.Close();
}
}
}
}
and then instead of allocating/attaching a console to the current application, the echo server can be started from within the application and Console's output stream can be redirected to write to the pipe server.
class Program
{
private static NamedPipeClientStream _pipeClient;
static void Main(string[] args)
{
//Current application is a Win32 application without any console window
var processStartInfo = new ProcessStartInfo("echoserver.exe");
Process serverProcess = new Process {StartInfo = processStartInfo};
serverProcess.Start();
_pipeClient = new NamedPipeClientStream(".", #"Com.MyDomain.EchoServer.PipeServer", PipeDirection.Out, PipeOptions.None);
_pipeClient.Connect();
StreamWriter writer = new StreamWriter(_pipeClient) {AutoFlush = true};
Console.SetOut(writer);
Console.WriteLine("Testing");
//Do rest of the work.
//Also detect that the server has terminated (serverProcess.HasExited) and then close the _pipeClient
//Also remember to terminate the server process when current process exits, serverProcess.Kill();
while (true)
continue;
}
}
This is just one of the possible solutions. In essence the work around is to allot the console window to its own process so that it can terminate without affecting the parent process.
You can do this by disabling keyboard mouse input by external program called Keyfreez.
you can use it multiple times in your program where no user input required. And if any user input require u can add a process Takskkill /f /IM .
https://www.sordum.org/7921/bluelife-keyfreeze-v1-4-block-keyboard-and-mouse/
Hope this helps all of you

Detecting that the user is away from the PC with .NET

I have a desktop application in which I would like to know two things:
Is the user currently on the PC (more specifically, is he giving any input to the PC), so I can change his state to "away" if needed; and
Is the screensaver running right now, so I can perform more CPU intensive work during that time.
I'm using C#/.NET. How would you suggest to tackle these two tasks?
NOTE: WIN32 invocation will be just as good, as well as any unmanaged code solution.
http://dataerror.blogspot.com/2005/02/detect-windows-idle-time.html
^ Detect Windows Idle Time. :)
The enabler for this feature is the GetLastInputInfo() Win32 API and the LASTINPUTINFO Win32 structure.
Here is the code to detect if a screen saver is running. See this for more details
const int SPI_GETSCREENSAVERRUNNING = 114;
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
private static extern bool SystemParametersInfo(
int uAction, int uParam, ref bool lpvParam,
int flags );
// Returns TRUE if the screen saver is actually running
public static bool GetScreenSaverRunning( )
{
bool isRunning = false;
SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0,
ref isRunning, 0 );
return isRunning;
}
Rather than figuring out when to run more intensive work... Consider doing your "intensive work" as early as you can, but at a lower thread priority.
I don't think your questions have an answer in pure C#, unless you poll the mouse position and observe movements... Or something like that.
You could use a global keyboard/mouse hook and just reset your "counter" to 0 when you receive an event from either. When your counter reaches the idle time that you're looking for, perform your background actions.
There is some code here that allows you to easily do the hooking in .NET: http://www.codeproject.com/KB/cs/globalhook.aspx

Can I disable window autoplay function programatically with C#/.NET?

Does anybody know a way to deactivate the autoplay function of windows using c#/.NET?
A little summary, for all the others looking for a good way to disable/supress autoplay.
So far I've found 3 methods to disable autoplay programatically:
Intercepting the QueryCancelAutoPlay message
Using the Registry
Implementing the COM Interface IQueryCancelAutoPlay
In the end I chose the 3rd method and used the IQueryCancelAutoPlay interface because the others had some signifcant disadvantages:
The first method
(QueryCancelAutoPlay) was only able
to suppress autoplay if the
application window was in the foreground, cause only the foreground window receives the message
Configuring autoplay in the registry worked even if the application window was in the background. The downside: It required a restart of the currently running explorer.exe to take effect...so this was no solution to temporarily disable autoplay.
Examples for the implementation
1. QueryCancelAutoPlay
Suppressing AutoRun Programmatically (MSDN article)
CodeProject: Preventing a CD from Auto-Playing
Canceling AutoPlay from C#
Note: If your application is using a dialog box you need to call SetWindowLong (signature) instead of just returning false. See here for more details)
2. Registry
Using the registry you can disables AutoRun for specified drive letters (NoDriveAutoRun) or for a class of drives (NoDriveTypeAutoRun)
Using the Registry to Disable AutoRun (MSDN article)
How to Enable / Disable Autorun for a Drive (using Registry)
Windows 7 AutoPlay Enable | Disable
3. IQueryCancelAutoPlay
Reference for the IQueryCancelAutoPlay interface on MSDN
IQueryCancelAutoPlay only called once? (Example implementatio, also read comments)
AutoPlayController (another implementation, not tested)
Some other links:
Enabling and Disabling AutoRun (MSDN article)
Autoplay in Windows XP: Automatically Detect and React to New Devices on a System (an old but extensive article on Autoplay)
RegisterWindowMessage is a Win32 API call. So you will need to use PInvoke to make it work..
using System.Runtime.InteropServices;
class Win32Call
{
[DllImport("user32.dll")]
public static extern int RegisterWindowMessage(String strMessage);
}
// In your application you will call
Win32Call.RegisterWindowMessage("QueryCancelAutoPlay");
From here (The Experts-Exchange link at the top). There is additional help on that site with some more examples that may be a little more comprehensive than the above. The above does however solve the problem.
Some additional links that might be helpful:
Preventing a CD from
Auto-Playing shows some example
vb.net code, showing the usage of
"QueryCancelAutoPlay" on CodeProject.
Enabling and Disabling AutoRun on MSDN.
Try this code work for me :) For more info check out this reference link : http://www.pinvoke.net/default.aspx/user32.registerwindowmessage
using System.Runtime.InteropServices;
//provide a private internal message id
private UInt32 queryCancelAutoPlay = 0;
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
/* only needed if your application is using a dialog box and needs to
* respond to a "QueryCancelAutoPlay" message, it cannot simply return TRUE or FALSE.
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
*/
protected override void WndProc(ref Message m)
{
//calling the base first is important, otherwise the values you set later will be lost
base.WndProc (ref m);
//if the QueryCancelAutoPlay message id has not been registered...
if (queryCancelAutoPlay == 0)
queryCancelAutoPlay = RegisterWindowMessage("QueryCancelAutoPlay");
//if the window message id equals the QueryCancelAutoPlay message id
if ((UInt32)m.Msg == queryCancelAutoPlay)
{
/* only needed if your application is using a dialog box and needs to
* respond to a "QueryCancelAutoPlay" message, it cannot simply return TRUE or FALSE.
SetWindowLong(this.Handle, 0, 1);
*/
m.Result = (IntPtr)1;
}
} //WndProc

Prevent Pocket PC device from Shutting down application on power off

How can I prevent the pocket PC device from shutting down from my application when the power button pressed? I am using C#.
You could use the Microsoft.WindowsCE.Form.MessageWindows class to intercept the Power Button event. This solution will not be portable, as the hardware key will be different in different machines.
I recommend however that you don't disable power down completely. Have a look at my answer in another question here. You could also use openetcf to easily create power down events handlers and register wake up events. You should implement the application logic based on what you are trying to achieve, for instance wake up every one minute to run a process.
You can try changing the power requirements for the device "BLK1:", which is the blacklight device. Be aware that the behavior may not be the same on all devices and version of the OS or Vendor specific Extensions.
To do this, you can write something like :
[DllImport("coredll")]
private extern static IntPtr SetPowerRequirement(string pvDevice, int deviceState,
int deviceFlags, IntPtr pvSystemState, int stateFlags);
[DllImport("coredll")]
private extern static int ReleasePowerRequirement(IntPtr handle);
and call it this way :
IntPtr handle = SetPowerRequirement("BLK1:", 0 /* D0, Full On */, 1, IntPtr.Zero, 0);
// Do something that requires the device to stay on ...
ReleasePowerRequirement(handle);
But this is generally not a good practice, leaving a device with the backlight on for extended periods might reduce dramatically its autonomy.

Categories