How to interrupt Screen-saver under windows 8 - c#

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.

Related

Get the window handle of the Windows setup process

I am trying to automate Windows 10 installation by first mounting the .iso file on the drive. And then using c# to start windows 10 installation by using this below code which passes the keys to the installation application
[DllImport("user32.dll")]
static extern int SetForegroundWindow(IntPtr point);
public static void Main(String[] args){
Process p1 = Process.Start("h:\\setup.exe");
IntPtr h = p1.MainWindowHandle;
SetForegroundWindow(h);
Thread.Sleep(30000);
SendKeys.SendWait("{ENTER}");
Thread.Sleep(1000);
SendKeys.SendWait("{ENTER}");
Thread.Sleep(1000);
SendKeys.SendWait("{ENTER}");
}
But the problem is that the setup window is not taking the signal of the ENTER key in the code. The setup window is starting with this code. After that, nothing is happening.
Process p1 = Process.Start("h:\\setup.exe");
I tried using notepad instead of setup.exe in the code which is taking all the ENTER keys. Please tell me if anyone has a solution. Thank you
Disclaimer:
I would advise against automating a Windows setup using something like
SendKeys as you can't guarantee a consistent behavior and could
easily mess things up. You may consider looking for different
approaches as suggested by lan Kemp in the comments. This answer
only shows you how to get the handle of the setup window correctly.
You may use it at your own risk.
Update:
Apparently, the Windows 10 setup executable ("Setup.exe") starts another process called "SetupPrep.exe" which starts a third process called "SetupHost.exe" (the one you're after). So, what you can do is start the main process, wait for the target process to start and obtain a MainWindowHandle before executing the remaining code:
Process p1 = Process.Start("H:\\setup.exe");
Process targetProcess;
do
{
Thread.Sleep(500);
targetProcess = Process.GetProcessesByName("SetupHost").FirstOrDefault();
} while (targetProcess == null || targetProcess.MainWindowHandle == IntPtr.Zero);
IntPtr h = targetProcess.MainWindowHandle;
// ...
This should solve your problem, however, it's not a wise idea to use SendKeys for this purpose. Please refer to the disclaimer above.
Original answer:
Did you make sure that h does actually have a value (other than IntPtr.Zero)? Because it probably doesn't have the actual window handle since you don't give the process enough time to start and obtain a window handle.
Try something like this:
Process p1 = Process.Start("h:\\setup.exe");
while (p1.MainWindowHandle == IntPtr.Zero)
{
Thread.Sleep(500);
}
IntPtr h = p1.MainWindowHandle;
// ...

How to prevent Windows from entering idle state?

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

Windows Console Application Getting Stuck (Needs Key Press) [duplicate]

This question already has answers here:
How and why does QuickEdit mode in Command Prompt freeze applications?
(2 answers)
Closed 6 years ago.
I have a console program that has different components that run like this:
void start() {
while(true){
DoSomething();
Thread.Sleep(1000*5);
}
}
My main entry point looks like [pseudo-ish code]
Thread.Start(Componenet1.Start);
Thread.Start(Componenet2.Start);
while(true){
Console.Writeline("running");
Thread.Sleep(1000*5);
}
There are no Console.Reads anywhere. My problem is SOMETIMES the application will be running great but then stop and if I press any key on the window it will start working again. This happens fairly infrequently but I have this program deployed on 100+ VM's running 24/7 in an automated environment.
Also on the computer I have some AHK scripts and other stuff that manipulate the mouse but not sure if that has anything to do with it.
Also note that sometimes the CPU can really be running at 100% on the machines so maybe thread priority is an issue?
SOLUTION: You need to disable quick edit mode. Here is working C# code to do this:
// http://msdn.microsoft.com/en-us/library/ms686033(VS.85).aspx
[DllImport("kernel32.dll")]
public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
private const uint ENABLE_EXTENDED_FLAGS = 0x0080;
static void Main(string[] args)
{
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
SetConsoleMode(handle, ENABLE_EXTENDED_FLAGS);
If the user accidentally clicks into the black console window, the cursor changes to a filled white rectangle, and the app hangs at the next Console.Write statement, until another clic is made.
It is a generic feature of the Console window when its "QuickEdit Mode" is enabled.
In order to disable that feature, you should uncheck the "QuickEdit Mode" option of your app's console window at run-time.

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