Alt+F,S not working in sendKeys C# - c#

I want to save and close all kinds of application which is opened. The specific application is identified from Process command. with this I can kill it.
For saving I tried SendKeys class, First I set the SetForegroundWindow(h), and succeeded with ctrl+s by using
SendKeys.Send("^s"); //Ctrl+s
but, user defined applications are there, and also I have a situation to save a new(not existing file) which has to be saved by Alt+F+S.
So that it saves with default name
How do I achieve this,
I tried,
SendKeys.Send("%(fs)");
SendKeys.Send("%f"+"s"); //Alt+F
SendKeys.Send("%f" + "%s)"); //Alt+F
SendKeys.Send("%fs");
Please guide me, If its not possible with SendKeys, what else should I try.

Always use the breakets and you can avoid errors.
SendKeys.Send("%{f}"); //Alt+F
SendKeys.Send("{A}"); //A
or try
SendKeys.Send("%{f}{A}"); //Alt+F And A

What APP? SendKeys will send key strokes but under the hood most things use the good old message loop.
SendMessage(hWnd, WM_SETTEXT, wParam, lParam);
c#
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, String lpWindowName);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
IntPtr hwnd= FindWindow(null, "Window Title");
SendMessage(hwnd, id, IntPtr.Zero, IntPtr.Zero);
To get notepad to save it would be
const int WM_COMMAND = 0x111;
SendMessage(hwnd, WM_COMMAND,777 , NULL);

Related

Capture events from other windows applications

I have a third party application which I did not create myself. I need to create an application which is able to listen for button clicks and read data from tables in that application. I believe that the third party application is made in C# but I do not know for sure. Is there a way to know when UI buttons are pressed and to harvest data from the application? I do not mind which programming language the solution must be written in, as long as it fulfils the above tasks.
You can use few dlls like user32.dll, to get data from other apps.
Find parent handle of a window:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public static IntPtr FindWindow(string windowName)
{
var hWnd = FindWindow(windowName, null);
return hWnd;
}
After that, find handle of a child window
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
private IntPtr FindSomeElement(IntPtr parent)
{
IntPtr childHandle;
childHandle = FindWindowEx(
parent,
IntPtr.Zero,
"WindowsForms10.EDIT.app21",
IntPtr.Zero);
return childHandle;}
and get text from it:
private static string GetText(IntPtr childHandle)
{
const uint WM_GETTEXTLENGTH = 0x000E;
const uint WM_GETTEXT = 0x000D;
var length = (int)SendMessage(handle, WM_GETTEXTLENGTH, IntPtr.Zero, null);
var sb = new StringBuilder(length + 1);
SendMessage(handle, WM_GETTEXT, (IntPtr)sb.Capacity, sb);
return sb.ToString();
}
//I didnt test this code, just gave an idea.
Visit www.pinvoke.net/default.aspx/ for more information. You can find alot about user32.dll

Notepad - force to show save dialog when content provided by SendMessage pinvoke

I have simple helper method which allows me to open notepad.exe and fill it by provided text.
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", EntryPoint = "SendMessageW")]
public static extern IntPtr SendMessageW(IntPtr hWnd, UInt32 msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
public static void OpenNotepadWithText(string text)
{
var process = Process.Start("notepad.exe");
if (process == null)
throw new Exception("Unable to run notepad.exe process!");
process.WaitForInputIdle();
IntPtr child = FindWindowEx(process.MainWindowHandle, new IntPtr(0), "Edit", null);
SendMessageW(child, 0x000C, IntPtr.Zero, text);
}
When I click on close button of notepad, notepad is closed without asking for save. It seems that used approach does not set "need_to_save" flag in notepad and thus notepad thinks that there is no changed content to save. Can someone help me with setting this flag?

Repeat FindWindow function everytime the window appears/opens

The title says it all, I have this code:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
const UInt32 WM_CLOSE = 0x0010;
and here's what I added to Form1_Load:
IntPtr windowPtr = FindWindowByCaption(IntPtr.Zero, "Untitled - Notepad");
if (windowPtr == IntPtr.Zero)
{
MessageBox.Show("Window not found");
return;
}
SendMessage(windowPtr, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
so I added the code above to the Form1_Load function, and it actually works, it closes notepad when I open my program, but my question is, how to make the function repeat, like close notepad whenever it opens and not only on Form1_Load ?
You have to enumerate the windows yourself: EnumWindows and in the return procedure check if the title is the same as what you want (hardcoding 'Untitled' might not be the best way by the way). Alternatively traverse the window graph yourself with GetWindow, starting at the first desktop child and iterate the siblings from there.
Also you don't need the IntPtr version of FindWindow, you can pass null as a string parameter and it accomplishes the same.

am working in an application and I press key from keyboard, how can I capture that key (or string), including the source application's name, using C#?

i am working in an application and I press key from keyboard, how can I capture that key (or string), including the source application's name, using C#? i am working on a application, in this application i want to store keystrokes with source application for example if i working with notepad and i type " this is a pen" in notepad.
i have a list view with 3 column( application name, application path, window caption) now in application name column show the program which is open. now if notepad is open then it is showing in list view and i type some text in notepad. i want to store that text in a file which i typed in notepad, this is a console application but i wannna do it in windows application.
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class InterceptKeys
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public static void Main()
{
_hookID = SetHook(_proc);
Application.Run();
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelKeyboardProc(
int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
I don't think that this is best performed with C#, primarily because you will be needing to delve deeply within the Windows API, which obviates the basic presmise behind .NET in that it is platform independent.
As already stated by Anton you'll need to use Windows Hooks and process the WH_KEYBOARD type hook.
You probably would like to look at windows hooks.
Implementing what you want isn't a trivial task anyway because in order to get all keystrokes from all windows in the system you must get inside a window message processing mechanism of the operating system.
After all, I wouldn't suggest implementing windows hook that works under CLR. This may be disastrous to the whole OS in case you make a mistake and I'm not sure whether it is even possible.
It means either dig into C/C++ and write a global hook dll intercepting all keystrokes and implement interop with that dll or try to find a way of solving your problem without involving keystrokes capturing.
There are many managed wrappers for doing Global System Hooks for mouse and keyboard. The best implementation I've found is :
http://www.codeproject.com/KB/system/globalsystemhook.aspx
This will allow you to set a global keyboard hook and capture keystrokes in notepad. I've used it before and it's very easy to setup. Make sure you unhook when your app terminates.
Now to get the title of the window as you described in the second part of your requirements, you would need to get the current foreground window when you receive the keys from the hook. You can again use the Windows API functions GetForegroundWindow, and GetWindowText for that.
You could also get the process associated with the current foreground window by using Windows API GetWindowThreadProcessID and then using the managed framework System.Diagnostics.Process.GetProcessById() get all sorts of useful information about the source of the keystrokes.
You can look up information on how to implement all said Windows API Functions on pinvoke.net

How to write and send text to mIRC in C#/Win32?

In a previous question, I asked how to send text to Notepad. It helped me immensely. For part 2, here's a simplified version of the same applied mIRC:
[DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
IntPtr mainHandle = FindWindow("mIRC", null);
IntPtr serverHandle = FindWindowEx(mainHandle, new IntPtr(0), "MDIClient", null);
IntPtr chanHandle = FindWindowEx(serverHandle, new IntPtr(0), "mIRC_Channel", null);
IntPtr editHandle = FindWindowEx(chanHandle, new IntPtr(0), "Edit", null);
SendMessage(editHandle, 0x000C, 0, textBox1.Text);
This seems correct to me, except that it doesn't work! Is it that the window names are incorrect (MDIClient, mIRC_Channel, and Edit)? These are values I found on a web site by googling "FindWindowEx mIRC".
1.) What am I doing wrong in the above?
2.) For reference, in general is there an easy way to find all the Window names for use with FindWindowEx()?
This code works for me (mirc 6.31):
IntPtr mainHandle = FindWindow("mIRC", null);
IntPtr serverHandle = FindWindowEx(mainHandle, new IntPtr(0), "MDIClient", null);
IntPtr chanHandle = FindWindowEx(serverHandle, new IntPtr(0), "mIRC_Channel", null);
IntPtr editHandle = FindWindowEx(chanHandle, new IntPtr(0), "richEdit20A", null);
SendMessage(editHandle, 0x000C, 0, "Hello World");
Notice the changed window class (richedit20A instead of edit). Just found the correct class by using Spy++.
As for the window handles, one possibility is to use the EnumWindows or EnumChildWindows API.

Categories