Hopefully this is a simple one, but can anyone provide some simple c# code that will launch the currently configured screensaver?
Here is a good site showing how to work with all aspects of the screensaver. See the comments at the end for the code to start the screensaver.
http://www.codeproject.com/KB/cs/ScreenSaverControl.aspx
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
private static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
//...
private const int SC_SCREENSAVE = 0xF140;
private const int WM_SYSCOMMAND = 0x0112;
//...
public static void SetScreenSaverRunning()
{
SendMessage
(GetDesktopWindow(), WM_SYSCOMMAND, SC_SCREENSAVE, 0);
}
Related
I'm trying to Postmessage send key inputs to an application. The issue is that the message is being sent only when the application becomes active or gains focus.
Here is my goal:
I need the application to receive inputs either while it is not focused, or via some pseudo-focus called via postmessage before the input is sent (I have tried: NativeMethods.PostMessage(mainHwnd, 0x0007, 0, 0); "0x0007" is WM_SETFOCUS but this doesn't do anything). Any assistance would be very helpful, I've been at this for more hours than I care to count.🙏
Here is all of the relevant code I'm using:
using System.Runtime.InteropServices;
using System;
using System.Windows.Forms;
using System.Threading;
internal static class NativeMethods
{
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, UInt32 uMsg, Int32 wParam, Int32 lParam);
}
class Test
{
const int WM_KEYDOWN = 0x0100;
const int WM_KEYUP = 0x0101;
//const int WM_SETFOCUS = 0x0007;
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
public static void SendKey()
{
IntPtr mainHwnd = NativeMethods.FindWindow(null, "Test Application");
NativeMethods.PostMessage(mainHwnd, WM_KEYDOWN, (int)Keys.A, 0);
Thread.Sleep(50);
NativeMethods.PostMessage(mainHwnd, WM_KEYUP, (int)Keys.A, 0);
}
}
class TryTheThing{
public void Send() {
Test.SendKey();
}
}
Windows does not allow you to send keystrokes to non-focused applications. Your only option is to force the window to be focused first. This can be achieved by P/Invoking SetForegroundWindow():
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
NativeMethods.SetForegroundWindow(mainHwnd);
I'm trying to make a Unity3D Application that can control the volume of another application. So far I've gotten it to work to change the volume of ALL applications, but I'm having trouble to get it to change just one, e.g. Spotify. This is on Windows 8, but I'd like it to work for Windows 7 as well.
private const int APPCOMMAND_VOLUME_UP = 0xA0000;
private const int APPCOMMAND_VOLUME_DOWN = 0x90000;
private const int WM_APPCOMMAND = 0x319;
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string strClassName, string strWindowName);
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
[DllImport("user32.dll")]
public static extern IntPtr GetActiveWindow();
public void DecreaseVolume()
{
IntPtr hWnd = FindWindow("SpotifyMainWindow", "Spotify");
if (hWnd == IntPtr.Zero)
return;
uint pID;
GetWindowThreadProcessId(hWnd, out pID);
Debug.Log(pID);
SendMessage(hWnd, WM_APPCOMMAND, hWnd, (IntPtr)APPCOMMAND_VOLUME_DOWN);
}
public void IncreaseVolume()
{
// same as above, but with APPCOMMAND_VOLUME_UP
}
I'm pretty sure I'm getting the correct handle (hWnd) from FindWindow() because the pID printed out matches the PID of Spotify in my Task Manager, however all this does is change the volume of everything instead of just Spotify. This is the same result as if I didn't specify a specific handle e.g.
SendMessage(IntPtr.Zero, WM_APPCOMMAND, IntPtr.Zero, (IntPtr)APPCOMMAND_VOLUME_DOWN);
or if I use GetActiveWindow().
I've never messed around with these windows api stuff until today, so any help would be very appreciated!
I have list of open Applications. To get this list i have used following code
internal static class NativeMethods
{
public static readonly Int32 GWL_STYLE = -16;
public static readonly UInt64 WS_VISIBLE = 0x10000000L;
public static readonly UInt64 WS_BORDER = 0x00800000L;
public static readonly UInt64 DESIRED_WS = WS_BORDER | WS_VISIBLE;
public delegate Boolean EnumWindowsCallback(IntPtr hwnd, Int32 lParam);
public static List<WindowWrapper> GetAllWindows()
{
List<WindowWrapper> windows = new List<WindowWrapper>();
StringBuilder buffer = new StringBuilder(100);
EnumWindows(delegate(IntPtr hwnd, Int32 lParam)
{
if ((GetWindowLongA(hwnd, GWL_STYLE) & DESIRED_WS) == DESIRED_WS)
{
GetWindowText(hwnd, buffer, buffer.Capacity);
WindowWrapper wnd = new WindowWrapper();
wnd.handle = hwnd;
wnd.title = buffer.ToString();
windows.Add(wnd);
}
return true;
}, 0);
return windows;
}
[DllImport("user32.dll")]
static extern Int32 EnumWindows(EnumWindowsCallback lpEnumFunc, Int32 lParam);
[DllImport("user32.dll")]
public static extern void GetWindowText(IntPtr hWnd, StringBuilder lpString, Int32 nMaxCount);
[DllImport("user32.dll")]
static extern UInt64 GetWindowLongA(IntPtr hWnd, Int32 nIndex);
}
public class WindowWrapper : IWin32Window
{
internal IntPtr handle;
internal String title;
public IntPtr Handle
{
get { return handle; }
}
public String Title
{
get { return title; }
}
}
to call this i used following code
foreach (var wnd in NativeMethods.GetAllWindows())
{
string caption = wnd.title;
string handle = wnd.Handle
// Add this caption and handle to list
}
Now, User will select any of the opened window from the list and my task is to read caption of the selected window, get handle of process and maximize/minimize or close window. How can I do this.
You can use findwindowbycaption to get the handle then maximize or minimize with showwindow
private const int SW_MAXIMIZE = 3;
private const int SW_MINIMIZE = 6;
// more here: http://www.pinvoke.net/default.aspx/user32.showwindow
[DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
Then in your code you use this:
IntPtr hwnd = FindWindowByCaption(IntPtr.Zero, "The window title");
ShowWindow(hwnd, SW_MAXIMIZE);
Although it seems you already have the window handle by using EnumWindows in that case you would only need:
ShowWindow(windows[i].handle, SW_MAXIMIZE);
i is the index of the window.
to close the window you will use:
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DestroyWindow(IntPtr hwnd);
in the code:
DestroyWindow(hwnd) //or DestroyWindow(windows[i].handle)
this is the unmanaged version of system.windows.forms.form.close()
or you can use:
Process [] proc Process.GetProcessesByName("process name");
proc[0].Kill();
or you can use:
static uint WM_CLOSE = 0x0010;
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
in code:
PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
You may use native method ShowWindow with SW_MAXIMIZE, SW_MINIMIZE for ncmdShow
Take a look at http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
private const int SW_MAXIMIZE = 3;
private const int SW_MINIMIZE = 6;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);
// in your code
ShowWindow(wnd.Handle, SW_MAXIMIZE);
you can use ShowWindowAsync
private const int SW_SHOWNORMAL = 1;
private const int SW_SHOWMINIMIZED = 2;
private const int SW_SHOWMAXIMIZED = 3;
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
ShowWindowAsync(wnd.Handle, SW_SHOWMINIMIZED );
and it's better and to use
var openWindows = Process.GetProcesses().Where(process=> String.IsNullOrEmpty(process.MainWindowTitle)==false);
to get opened windows
I have test MainWindowTitle in Porcess and it helps to search on window given it's caption.
var handles = Process.GetProcesses().Where(x => x.MainWindowTitle == "Untitled - Notepad").Select(y=>y.Handle).ToList();
How can I close a window of external application programmatically in VB.net.
I just want to close the current window without closing the whole process.
use FindWindow and SendMessage APIs
here in C#, should be trivial to convert:
using Microsoft.Win32;
[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName,string lpWindowName);
[DllImport("user32.dll")]
public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
public const int WM_SYSCOMMAND = 0x0112;
public const int SC_CLOSE = 0xF060;
private void closeWindow()
{
// retrieve the handler of the window
int iHandle = FindWindow("Notepad", "Untitled - Notepad");
if (iHandle > 0)
{
// close the window using API
SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
}
}
source: http://www.codeproject.com/KB/dialog/closewindow.aspx
This is with reference to this question:
How to read output and give input to a program from c program?
I found the answer to the above question very useful. In the same way, can I do it for windows applications? Like can I give input into a Windows form (like .net, C# applications) application's text box programmatically? Can I do the action of button click from a program?
If so, can I do it from a C program (with Tiny C compiler or any other on windows platform)? If not, how and in which language can I do it? Please don't take it as a silly question. Any example codes will be very much appreciated.
Edit: Can I do the same with web applications and web pages?
If your application mainly just needs to manipulate other windows, by sending keystrokes etc. i would use AutoIt. It's mainly function is exactly this job and it does it very well.
So maybe you should give it a try, cause not every problem is a nail and can be solved with a hammer (C#) ;-))
You can enumerate all the windows of the system.
You can send windows messages to any window.
E.g. to set the text of a textbox you have to send a WM_SETTEXT message.
FYI: Winspector is a very interesting tool which makes heavy use of this as well (also to debug or otherwise first inspect the windows you're trying to programmatically access).
You might also be interested in this:
AutoIt v3 is a freeware BASIC-like scripting language designed for automating the Windows GUI and general scripting. It uses a combination of simulated keystrokes, mouse movement and window/control manipulation in order to automate tasks in a way not possible or reliable with other languages (e.g. VBScript and SendKeys). AutoIt is also very small, self-contained and will run on all versions of Windows out-of-the-box with no annoying "runtimes" required!
As fretje pointed out, you can certainly do it.
It's much more challenging for windows apps. Because individual controls also count as windows, the total window count will be much higher than you might expect; and finding the specific control you want to send input to can take a lot of work.
But you can programmatically move, resize, check, fill, maximize or otherwise affect an app's windows, once you know which one is your target.
I wrote code to do the discovery process a few years ago. It found all the windows of a target app, then using their size & location data, produced a translucent overlay of each child window, along with the handle number. So I could visually tell which control went with which handle.
EDIT: Added some code. This is some basic C# interop code that will let you make easy calls into user32.dll, which holds the fns to which fretje referred. This just gives you the basic calls for discovery and manipulation; you'll still have to do the hard work of enumerating and examining what you find. If you can find a 3rd-party package that does the job for you, save yourself the trouble; I only did it as a learning experience, and it was pretty laborious.
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;
namespace WinAPI
{
[Flags] public enum WindowStyleFlags : uint
{
WS_OVERLAPPED = 0x00000000,
WS_POPUP = 0x80000000,
// more...
}
[Flags] public enum ExtendedWindowStyleFlags: int
{
WS_EX_DLGMODALFRAME = 0x00000001,
WS_EX_NOPARENTNOTIFY = 0x00000004,
// more...
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct POINT
{
public int Left;
public int Top;
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct FLASHWINFO
{
public int cbSize;
public IntPtr hwnd;
public int dwFlags;
public int uCount;
public int dwTimeout;
}
public delegate int EnumWindowsCallback( IntPtr hwnd, int lParam );
public class User32Dll
{
// Constants & fields
public const int FLASHW_STOP = 0;
public const int FLASHW_CAPTION = 0x00000001;
// lots, lots more, web search for them...
// Self-added, don't know if correct
[DllImport("user32")]
public extern static bool CloseWindow( IntPtr hWnd );
[DllImport("user32")]
public extern static IntPtr GetDesktopWindow();
[DllImport("user32")]
public extern static IntPtr GetForegroundWindow();
[DllImport("user32")]
public extern static int GetDlgItem( IntPtr hWnd, int wMsg );
[DllImport("user32")]
public extern static int GetListBoxInfo( IntPtr hWnd );
[DllImport("user32")]
public extern static bool MoveWindow( IntPtr hWnd, int X, int Y, int Width, int Height, bool Repaint );
[DllImport( "user32" )]
public static extern int SendMessage( IntPtr hWnd, int uMsg, IntPtr wParam, StringBuilder lpString );
[DllImport("user32")]
public static extern bool SetWindowPos( IntPtr hWnd, IntPtr afterWnd, int X, int Y, int cX, int cY, uint uFlags );
[DllImport("user32")]
public extern static int BringWindowToTop (IntPtr hWnd);
[DllImport("user32")]
public extern static int EnumWindows( EnumWindowsCallback lpEnumFunc, int lParam );
[DllImport("user32")]
public extern static int EnumChildWindows( IntPtr hWndParent, EnumWindowsCallback lpEnumFunc, int lParam );
[DllImport( "user32.dll" )]
public static extern int EnumThreadWindows( IntPtr hWndParent, EnumWindowsCallback callback, int lParam );
[DllImport( "user32.dll" )]
public static extern int FindWindow( string lpClassName, string WindowName );
[DllImport( "user32.dll" )]
public static extern int FindWindowEx( IntPtr hWnd, IntPtr hWnd2, string lpsz, string lpsz2 );
[DllImport("user32")]
public extern static int FlashWindow ( IntPtr hWnd, ref FLASHWINFO pwfi);
[DllImport("user32")]
public extern static IntPtr GetAncestor( IntPtr hWnd, uint gaFlags );
[DllImport("user32", CharSet = CharSet.Auto)]
public extern static int GetClassName ( IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32", CharSet = CharSet.Auto)]
public extern static uint GetWindowLong( IntPtr hwnd, int nIndex);
[DllImport("user32")]
public extern static int GetClientRect( IntPtr hWnd, ref RECT lpRect);
[DllImport("user32")]
public extern static int GetWindowRect( IntPtr hWnd, ref RECT lpRect);
[DllImport("user32", CharSet = CharSet.Auto)]
public extern static int GetWindowText( IntPtr hWnd, StringBuilder lpString, int cch );
[DllImport("user32", CharSet = CharSet.Auto)]
public extern static int GetWindowTextLength( IntPtr hWnd );
[DllImport("user32")]
public extern static int IsIconic(IntPtr hWnd);
[DllImport("user32")]
public extern static int IsWindowVisible( IntPtr hWnd );
[DllImport("user32")]
public extern static int IsZoomed(IntPtr hwnd);
[DllImport("user32", CharSet = CharSet.Auto)]
public extern static int PostMessage( IntPtr hWnd, int wMsg, int wParam, int lParam);
[DllImport( "user32.dll" )]
public static extern int RealGetWindowClass( IntPtr hWnd, StringBuilder pszType, uint bufferSize );
[DllImport("user32")]
public extern static int ScreenToClient( IntPtr hWnd, ref POINT lpPoint);
[DllImport("user32", CharSet = CharSet.Auto)]
public extern static int SendMessage( IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public extern static int SetForegroundWindow (IntPtr hWnd);
[DllImport( "user32.dll" )]
public static extern int SetWindowText( IntPtr hWnd, string lpsz );
}
}
Check out the following SO question. There are numerous vendor and open-source tools to do this for you, so you don't have to code at to the Win32 API.
automated-testing-of-windows-forms