Preventing Lock screen from Console Application [duplicate] - c#

I am writing an application in C# that plays a movie. I need to figure out how to disable the screen saver and power options using C#.
I know the Windows SDK API has a function called SetThreadExecutionState() which can be used to do this, however, I do not know if there is a better way to do it. If not, how do I incorporate this function into C#?

Not sure if there is a better .NET solution but here is how you could use that API:
The required usings:
using System.Runtime.InteropServices;
The P/Invoke:
public const uint ES_CONTINUOUS = 0x80000000;
public const uint ES_SYSTEM_REQUIRED = 0x00000001;
public const uint ES_DISPLAY_REQUIRED = 0x00000002;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SetThreadExecutionState([In] uint esFlags);
And then disable screensaver by:
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
Finnaly enable screensaver by reseting the execution state back to original value:
SetThreadExecutionState(ES_CONTINUOUS);
Note that I just picked one of the flags at random in my example. You'd need to combine the correct flags to get the specific behavior you desire. You will find the description of flags on MSDN.

Related

How to make a monitoring program appear as wallpaper?

I made a simple C# program to display basic information about some machines we have. The program is full screen and refreshed every second. We have a dedicated PC and screen in the shop to display it constantly but some directors want it on their PC also, but appears as a wallpaper.
Please tell me if there is an easy way to set a program as a dynamic wallpaper, because I've found nothing.
I think the real solution would be to modify the program so that it runs minimized, and once in a while (like every 15 or 20 minute) it generates a image of the appearance when it is maximized, and then set that picture as the desktop wallpaper.
Does my solution make sense? How can I generate a picture from an hidden application?
Your solution makes sense.
You can change the background f:om C# with the following code but it only works with .bmp image types:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32 uiParam, String pvParam, UInt32 fWinIni);
private static UInt32 SPI_SETDESKWALLPAPER = 20;
private static UInt32 SPIF_UPDATEINIFILE = 0x1;
private String imageFileName = "c:\\sample.bmp";
public void SetImage( string filename )
{
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, filename, SPIF_UPDATEINIFILE);
}
For info on creating a .bmp during runtime, you may read this forum post.

P/Invoke problems with basic CRT functions (i.e., putchar, puts)

I've noticed something very strange. I was trying to call the CRT function "putchar", and was unable to get it to work. So I double-checked that I wasn't missing something, and I copied the code directly from the P/Invoke tutorial on MSDN to see if it worked.
http://msdn.microsoft.com/en-us/library/aa288468%28VS.71%29.aspx
You'll notice that they import "puts".
So I tested the exact code copied from MSDN. It didn't work! So now I got frustrated. I've never had this problem before.
Then I just so happened to run WITHOUT debugging (hit ctrl+f5), and it worked! I tested other functions which output to the console too, and none of them work when debugging but all work when not debugging.
I then wrote a simple C dll which exports a function called "PrintChar(char c)". When I call that function from C#, it works even if I'm debugging or not, without any problems.
What is the deal with this?
The Visual Studio hosting process is capable of redirecting console output to the Output window. How exactly it manages to do this is not documented at all, but it gets in the way here. It intercepts the WriteFile() call that generates the output of puts().
Project + Properties, Debug tab, untick "Enable the Visual Studio hosting process". On that same page, enabling unmanaged debugging also fixes the problem.
It's a bad example, using the C-Runtime Library DLL to call puts. Keep reading the tutorial as there is good info there, but try making Win32 API calls instead.
Here is a better introduction to p/invoke: http://msdn.microsoft.com/en-us/magazine/cc164123.aspx
It's old, but the information is still good.
Edited
My explaination was wrong.
I went looking for a correct explaination and I discovered that the C-Runtime puts method and the .NET Framework Console.Write method differ in how they write to the console (Console.Write works where the p/invoke to puts does not). I thought maybe the answer was in there, so I whipped up this demonstration:
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
class Program
{
public static void Main()
{
int written;
string outputString = "Hello, World!\r\n";
byte[] outputBytes = Encoding.Default.GetBytes(outputString);
//
// This is the way the C-Runtime Library method puts does it
IntPtr conOutHandle = CreateFile("CONOUT$", 0x40000000, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
WriteConsole(conOutHandle, outputBytes, outputString.Length, out written, IntPtr.Zero);
//
// This is the way Console.Write does it
IntPtr stdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
WriteFile(stdOutputHandle, outputBytes, outputBytes.Length, out written, IntPtr.Zero);
// Pause if running under debugger
if (Debugger.IsAttached)
{
Console.Write("Press any key to continue . . . ");
Console.ReadKey();
}
}
const int STD_OUTPUT_HANDLE = -11;
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
static extern int WriteFile(IntPtr handle, [In] byte[] bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess, FileShare dwShareMode, IntPtr securityAttrs, FileMode dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
static extern bool WriteConsole(IntPtr hConsoleOutput, [In] byte[] lpBuffer, int nNumberOfCharsToWrite, out int lpNumberOfCharsWritten, IntPtr mustBeZero);
}
Both of those successfully output under the debugger, even with the hosting process enabled. So that is a dead end.
I wanted to share it in case it leads someone else to figuring out why it happens -- Hans?

Change Windows Wallpaper using .NET 4.0?

Is there a way to change the Windows wallpaper using some new feature in .NET 4?
You can use SystemParametersInfo to set the desktop wallpaper. This should work consistently on all versions of windows that your app can run on, however will require some interop.
The following interop declarations are what you need
public const int SPI_SETDESKWALLPAPER = 20;
public const int SPIF_UPDATEINIFILE = 1;
public const int SPIF_SENDCHANGE = 2;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int SystemParametersInfo(
int uAction, int uParam, string lpvParam, int fuWinIni);
Which can be used like this to change the desktop wallpaper
SystemParametersInfo(
SPI_SETDESKWALLPAPER, 0, "filename.bmp",
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
You set the wallpaper by updating the registry. Here's an article from 2006 explaining how to do it. The details may have changed with newer versions of Windows, but the concept should be the same. Framework version should be irrelevant.
http://blogs.msdn.com/coding4fun/archive/2006/10/31/912569.aspx
Note that SystemParametersInfo will even return true, if the specified file does not exist! (on Windows 8 at least)
Plus you must give the full path to the file, not just a relative path.
Also on windows 7 and above this will create a new theme, and will turn off picture shuffling of course.

Determining type of running application (.NET)

How can I determine if the running application is a Windows Forms or a Console application?
You can't do this reliably. For example, start a new project from the Windows Forms Application project template. Project + Properties, change Output Type to "Console Application". Press F5 to see what that looks like. While every reasonable test will say it is a console mode application, it is very much a WF app.
The opposite is true as well, merely the presence of System.Windows.Forms.dll doesn't make it a WF app. A console app might use it to display a MessageBox for example.
Furthermore, it could be neither. Your code might be called by a service.
Punt this problem, the author of the app never has a problem telling you what your code should do. Add a property to your class to allow her to do so.
p/invoke:
[DllImport("shell32.dll")]
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
Struct:
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=80)]
public string szTypeName;
}
Method:
private static bool IsWindowsApplication(string fileName)
{
SHFILEINFO psfi = new SHFILEINFO();
switch (((int) SHGetFileInfo(fileName, 0, ref psfi, (uint) Marshal.SizeOf(psfi), 0x2000)))
{
case 0:
return false;
case 0x4550:
return false;
case 0x5a4d:
return false;
}
return true;
}
If the above method returns false, it's a console application.
-Oisin
If it doesn't need to be done programmatically you could maybe use a program like ProcessExplorer and see if the System.Winforms.dll is loaded. I don't think this is foolproof but it may be a start.
One option might be to check if System.Windows.Forms.Application.OpenForms contains any elements.
Another option might be to check whether Console.Title or Console.WindowTop throws an exception (it would if no console window is open).
EDIT
However, note that an application may have a console window and a form open at the same time... What kind of application is it then?

Controlling the volume while using the SndPlayAsync function on Windows Mobile 6

How on earth can you control the volume of the sound played using SndPlayAsync on Windows Mobile 6??
It seems like no one knows! The documentation doesn't mention anything regarding it...
So either there's no way, or it is kept top secret...
In addition, I am aware of the possibility of using the Windows Media Player, but I rather not, if possible.
Thanks for any help!
Aviv.
My suggestion is:
[DllImport("coredll.dll", SetLastError = true)]
protected static extern int waveOutSetVolume(IntPtr device, uint volume);
[DllImport("coredll.dll", SetLastError = true)]
internal static extern int waveOutGetVolume(IntPtr device, ref int volume);
And then you can call methods:
int before;
uint maxVol = uint.MaxValue;
waveOutGetVolume(IntPtr.Zero, ref before);
waveOutSetVolume(IntPtr.Zero, maxVol);
//Do some playing
waveOutSetVolume(IntPtr.Zero, before);
You can debug for other values. This will set it to highest.
Hope it helps?
You need to use the mixer... API functions to set the master volume. Here is a code sample:
http://www.csharp-home.com/index/tiki-read_article.php?articleId=134
To use this code in your Windows Mobile application, you need to change "winmm.dll" to "coredll.dll". Also, these methods may not be supported in Windows Mobile, but I'm pretty sure they are.

Categories