I'm trying to capture a Screensaver event, however when I run my application it throws the following exception;
Unable to find an entry point named 'SystemParametersinfo' in DLL 'user32.dll'.
this is my code so far, any and all help would be greatly appreciated =D
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NLog;
using Topshelf;
using OsWatch;
using Microsoft.Win32;
using System.Runtime.InteropServices;
namespace NotifyIcon
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SystemParametersinfo(int uAction, int uParam, ref int ipvParam, int fuWinini);
const int SPI_GETSCREENSAVERRUNNING = 114;
static int screenSaverRunning = -1;
int ok = SystemParametersinfo(SPI_GETSCREENSAVERRUNNING, 0, ref screenSaverRunning, 0);
private void ScreenSaver()
{
if (ok == 0)
{
Logger.Trace("SCREENSAVER OFF");
}
if (screenSaverRunning != 0)
{
Logger.Trace("SCREENSAVER ON");
}
}
Related
I need to set the background of a Windows form to the user's current Desktop wallpaper. How do I do this in C#?
Thanks
You can try the following code. I've tested this code on windows 8 and it works for me:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace StringFormatting
{
public partial class WallpaperTest : Form
{
private const UInt32 SPI_GETDESKWALLPAPER = 0x73;
private const int MAX_PATH = 260;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SystemParametersInfo(UInt32 uAction, int uParam, string lpvParam, int fuWinIni);
public WallpaperTest()
{
InitializeComponent();
this.BackgroundImage = GetCurrentDesktopWallpaper();
this.BackgroundImageLayout = ImageLayout.Stretch;
}
public Image GetCurrentDesktopWallpaper()
{
string currentWallpaper = new string('\0', MAX_PATH);
SystemParametersInfo(SPI_GETDESKWALLPAPER, currentWallpaper.Length, currentWallpaper, 0);
string imageAddress = currentWallpaper.Substring(0, currentWallpaper.IndexOf('\0'));
return Image.FromFile(imageAddress);
}
}
}
i'm writing a small "autosave" program for settlers 4.
The program should send "CTRL + S" every X seconds to make a quick-save ingame.
When i try the code below with notepad, everything works fine. But when i try it with the game (Settlers 4) it always opens the message box and tells me, that it can't find the game (game is running of course).
The game runs in fullscreen and doesn't need administrator rights, if that is important.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
namespace Siedler4Autosave2
{
public partial class Form1 : Form
{
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lp1, string lp2);
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
// Find Settlers 4
IntPtr handle = FindWindow("S4_Main", "Die Siedler IV");
if (!handle.Equals(IntPtr.Zero))
{
if (SetForegroundWindow(handle))
{
// send "CTRL + S"
SendKeys.Send("^(s)");
}
}
else
{
// Settlers 4 not found
MessageBox.Show("Siedler 4 nicht gefunden");
}
}
}
}
I'm using the WebBrowsercontrol in a WinForms application and have implemented my own download manager by following the instructions here.
My custom download manager works, but also overrides the download manager for Internet Explorer, too*. Is there a way to only have the custom download manager appear when my application is running? Or is there a way to unregistered it when my application closes?
*I appreciate that is precisely the point of implementing IDownloadManager, and the WebBrowser control is just, essentially, Internet Explorer (which is why I have gone down this route). The custom download manager provides exactly what I need, by allowing me to know what has been downloaded and where it has been downloaded to.
After weeks of research, I have finally managed to piece it together. Posting this here in the hopes that it will save someone the trauma I've been through.
IServiceProvider.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace BrowserExample
{
[ComImport, ComVisible(true)]
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryService(
[In] ref Guid guidService,
[In] ref Guid riid,
[Out] out IntPtr ppvObject);
}
}
IDownloadManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace BrowserExample
{
[ComVisible(false), ComImport]
[Guid("988934A4-064B-11D3-BB80-00104B35E7F9")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDownloadManager
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int Download(
[In, MarshalAs(UnmanagedType.Interface)] IMoniker pmk,
[In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc,
[In, MarshalAs(UnmanagedType.U4)] UInt32 dwBindVerb,
[In] int grfBINDF,
[In] IntPtr pBindInfo,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszHeaders,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszRedir,
[In, MarshalAs(UnmanagedType.U4)] uint uiCP);
}
}
DownloadManagerImplementation.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices.ComTypes;
using System.Windows.Forms;
namespace BrowserExample
{
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.Guid("bdb9c34c-d0ca-448e-b497-8de62e709744")]
public class DownloadManagerImplementation : IDownloadManager
{
/// <summary>
/// Return S_OK (0) so that IE will stop to download the file itself.
/// Else the default download user interface is used.
/// </summary>
public int Download(IMoniker pmk, IBindCtx pbc, uint dwBindVerb, int grfBINDF,
IntPtr pBindInfo, string pszHeaders, string pszRedir, uint uiCP)
{
// Get the display name of the pointer to an IMoniker interface that specifies
// the object to be downloaded.
string name = string.Empty;
pmk.GetDisplayName(pbc, null, out name);
if (!string.IsNullOrEmpty(name))
{
Uri url = null;
bool result = Uri.TryCreate(name, UriKind.Absolute, out url);
if (result)
{
//Implement your custom download manager here
//Example:
//WebDownloadForm manager = new WebDownloadForm();
//manager.FileToDownload = url.AbsoluteUri;
//manager.Show();
MessageBox.Show("Download URL is: " + url);
return 0; //Return S_OK
}
}
return 1; //unspecified error occured.
}
}
ExtendedBrowser.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace BrowserExample
{
public class ExtendedBrowser : WebBrowser
{
protected sealed class WebBrowserControlSite : WebBrowser.WebBrowserSite, IServiceProvider
{
DownloadManagerImplementation manager;
public WebBrowserControlSite(WebBrowser host)
: base(host)
{
manager = new DownloadManagerImplementation();
}
public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
{
Guid SID_SDownloadManager = new Guid("988934A4-064B-11D3-BB80-00104B35E7F9");
Guid IID_IDownloadManager = new Guid("988934A4-064B-11D3-BB80-00104B35E7F9");
if ((guidService == IID_IDownloadManager && riid == IID_IDownloadManager))
{
ppvObject = Marshal.GetComInterfaceForObject(manager, typeof(IDownloadManager));
return 0; //S_OK
}
ppvObject = IntPtr.Zero;
return unchecked((int)0x80004002); //NON_INTERFACE (use the default, please)
}
}
protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
{
return new WebBrowserControlSite(this);
}
}
}
To use it, just instantiate the ExtendedBrowser.
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace BrowserExample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var browser = new ExtendedBrowser();
this.Controls.Add(browser);
browser.Dock = DockStyle.Fill;
browser.Navigate("http://stackoverflow.com");
}
}
}
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test {
class Program {
static void Main(string[] args) {
for (int i = 0; i < 1000000000; i++) {
WindowHandler.testOverlay();
}
}
}
}
WindowHandler.cs:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Test {
static class WindowHandler {
private const String WINDOW_TITLE = "Minesweeper";
private static IntPtr windowHandle = IntPtr.Zero;
public static void testOverlay() {
if (windowHandle == IntPtr.Zero) {
windowHandle = getWindowHandle();
}
Graphics g = Graphics.FromHwnd(windowHandle);
g.FillRectangle(new SolidBrush(Color.White), 0, 0, 10000, 10000);
}
private static IntPtr getWindowHandle() {
foreach (Process proc in Process.GetProcesses()) {
if (proc.MainWindowTitle == WINDOW_TITLE) {
return proc.MainWindowHandle;
}
}
MessageBox.Show("Error: Unable to find window.");
return IntPtr.Zero;
}
}
}
I am not sure what I am doing wrong. I am writing a Minesweeper Solver and I am trying to overlay graphics on the Minesweeper window to provide debugging information. Unfortunately, it doesn't seem to work at all as I do not see any change on my screen. I am looping 1000000000 times in Program.cs just in case it erases my overlay on every frame refresh. I prefer to not try to hook DirectX.
I found a lot of questions about it, but no one explains how I can use this.
I have this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.FSharp.Linq.RuntimeHelpers;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
public class WindowHandling
{
public void ActivateTargetApplication(string processName, List<string> barcodesList)
{
[DllImport("User32.dll")]
public static extern int SetForegroundWindow(IntPtr point);
Process p = Process.Start("notepad++.exe");
p.WaitForInputIdle();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
SendKeys.SendWait("k");
IntPtr processFoundWindow = p.MainWindowHandle;
}
}
Can someone help me to understand why it gives me an error on the DllImport line and on the public static line?
Does anyone have an idea, what can I do?
Thank you.
You can't declare an extern local method inside of a method, or any other method with an attribute. Move your DLL import into the class:
using System.Runtime.InteropServices;
public class WindowHandling
{
[DllImport("User32.dll")]
public static extern int SetForegroundWindow(IntPtr point);
public void ActivateTargetApplication(string processName, List<string> barcodesList)
{
Process p = Process.Start("notepad++.exe");
p.WaitForInputIdle();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
SendKeys.SendWait("k");
IntPtr processFoundWindow = p.MainWindowHandle;
}
}
Starting with C# 9, your syntax would be valid if you remove the public keyword from the SetForegroundWindow deceleration:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.FSharp.Linq.RuntimeHelpers;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
public class WindowHandling
{
public void ActivateTargetApplication(string processName, List<string> barcodesList)
{
[DllImport("User32.dll")]
static extern int SetForegroundWindow(IntPtr point);
Process p = Process.Start("notepad++.exe");
p.WaitForInputIdle();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
SendKeys.SendWait("k");
IntPtr processFoundWindow = p.MainWindowHandle;
}
}
In C# 9 local functions can have attributes, see here