open new notepad.exe and write content to it [duplicate] - c#

This question already has answers here:
How to send text to Notepad in C#/Win32?
(3 answers)
Closed 7 years ago.
I would like to launch a new notepad instance and write content to it from my desktop app (WPF). After that it is user's discretion to save the file or not. (I know I can launch new notepad instance using System.Diagnostics.Process.Start("notepad.exe"))
Just like the process if some one manually wants to create a .txt file. He first opens notepad from start menu. Then write something and then save in desired folder.
Is it possible?

try this one source
[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);
private void button1_Click(object sender, EventArgs e)
{
Process [] notepads=Process.GetProcessesByName("notepad");
if(notepads.Length==0)return;
if (notepads[0] != null)
{
IntPtr child= FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null);
SendMessage(child, 0x000C, 0, textBox1.Text);
}
}

Related

How can i SendMessage to other processes windows then notepad?

In the top of form1
const int WM_SETTEXT = 0X000C;
//include FindWindowEx
[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
//include SendMessage
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
Then in the constructor
//getting notepad's process | at least one instance of notepad must be running
Process notepadProccess = Process.GetProcessesByName("devenv")[0];
//getting notepad's textbox handle from the main window's handle
//the textbox is called 'Edit'
IntPtr notepadTextbox = FindWindowEx(notepadProccess.MainWindowHandle, IntPtr.Zero, "Edit", null);
//sending the message to the textbox
SendMessage(notepadTextbox, WM_SETTEXT, 0, "Testing");
This is working for the notepad.
But if i want to send a message to another visual studio opened window of a project ?
For example i created a new project in a new visual studio and created in the project a new class called it test
And i want to send to the class some text for example:
using system;
For example this is the new class window:
After sending the message it will be like this:

C# - trigger key down event for active control

I found command System.Windows.Forms.SendKeys.Send() for sending keypress some key. This function work if open external app like a notepad and set focus and I will be see that my Key printed in this text field. How do same but with key down event, System.Windows.Forms.SendKeys.SendDown("A");, for example?
I tried call in Timer this command System.Windows.Forms.SendKeys.Send() but have runtime error associated with very fast taped.
You can't use the SendKeys class for that, unfortunately. You will need to go to a lower level API.
Poking a window with a keydown message
In Windows, keyboard events are sent to windows and controls via the Windows message pump. A piece of code using PostMessage should do the trick:
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
const uint WM_KEYDOWN = 0x0100;
void SendKeyDownToProcess(string processName, System.Windows.Forms.Keys key)
{
Process p = Process.GetProcessesByName(processName).FirstOrDefault();
if (p != null)
{
PostMessage(p.MainWindowHandle, WM_KEYDOWN, (int)key, 0);
}
}
Note that the application receiving these events may not do anything with it until a corresponding WM_KEYUP is received. You can get other message constants from here.
Poking a control other than the main window
The above code will send a keydown to the "MainWindowHandle." If you need to send it to something else (e.g. the active control) you will need to call PostMessage with a handle other than p.MainWindowHandle. The question is... how do you get that handle?
This is actually very involved... you will need to temporarily attach your thread to the window's message input and poke it to figure out what the handle is. This can only work if the current thread exists in a Windows Forms application and has an active message loop.
An explanation can be found here, as well as this example:
using System.Runtime.InteropServices;
public partial class FormMain : Form
{
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
[DllImport("user32.dll")]
static extern IntPtr AttachThreadInput(IntPtr idAttach,
IntPtr idAttachTo, bool fAttach);
[DllImport("user32.dll")]
static extern IntPtr GetFocus();
public FormMain()
{
InitializeComponent();
}
private void timerUpdate_Tick(object sender, EventArgs e)
{
labelHandle.Text = "hWnd: " +
FocusedControlInActiveWindow().ToString();
}
private IntPtr FocusedControlInActiveWindow()
{
IntPtr activeWindowHandle = GetForegroundWindow();
IntPtr activeWindowThread =
GetWindowThreadProcessId(activeWindowHandle, IntPtr.Zero);
IntPtr thisWindowThread = GetWindowThreadProcessId(this.Handle, IntPtr.Zero);
AttachThreadInput(activeWindowThread, thisWindowThread, true);
IntPtr focusedControlHandle = GetFocus();
AttachThreadInput(activeWindowThread, thisWindowThread, false);
return focusedControlHandle;
}
}
The good news-- if SendKeys worked for you, then you might not need to do all this-- SendKeys also sends messages to the main window handle.

SendKeys to a specific program without it being in focus

I am trying to use sendkeys, but send it to a non focused program. For example, I want to use sendkeys to Notepad - Untitled, without it being focused. Sorry if it's unclear, I will elaborate. My current code is this:
string txt = Regex.Replace(richTextBox3.Text, "[+^%~()]", "{$0}");
System.Threading.Thread.Sleep(1000);
SendKeys.Send(txt + "{ENTER}");
If I use SendMessage, would anyone care to show me an example of what I should do? I don't find anything I found online very useful for my issue.
The following code I found from a previous SO answer. The PostMessage API will send a Windows message to a specific Windows handle. The code below will cause the key down event to fire for all instances of Internet Explorer, without giving focus, simulating that the F5 key was pressed. A list of additional key codes can be found here.
static class Program
{
const UInt32 WM_KEYDOWN = 0x0100;
const int VK_F5 = 0x74;
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
[STAThread]
static void Main()
{
while(true)
{
Process [] processes = Process.GetProcessesByName("iexplore");
foreach(Process proc in processes)
PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK_F5, 0);
Thread.Sleep(5000);
}
}
}
It took me a while to figure it out for myself
Also here a usefull list of Virtual Key Codes
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern bool PostMessage(int hWnd, uint Msg, int wParam, int lParam);
private void button1_Click(object sender, EventArgs e)
{
const int WM_SYSKEYDOWN = 0x0104;
const int VK_RETURN = 0x0D;
IntPtr WindowToFind = FindWindow(null, "Notepad - Untitled"); // Window Titel
PostMessage(WindowToFind, WM_SYSKEYDOWN, VK_RETURN, 0);
}

Get untitled notepad contents [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am looking for a solution in c# or generally in any language which will do the following:
1) Let say you have an opened notepad and have write something inside. File is unsaved.
2) Via the program you will create save as "foo.txt" the notepad file and then close it.
In C# you can get process by name or id so you can have the process. But then how to make the process to save as and then close? Or maybe at least get the data of notepad and then i can save it via SystemIO.
But the problem is how from process get the data of the process and in my particular example get the notepad text (remember text is unsaved so no way to recover it from a path).
Thanks a lot.
Or maybe at least get the data of notepad
As the others have said, it's not the best approach by far...
...but sure, you can actually do that.
Here's an example that retrieves the contents of all open Notepad instances and spits them out in the Console:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private const int WM_GETTEXT = 0xd;
private const int WM_GETTEXTLENGTH = 0xe;
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, StringBuilder lParam);
private void button1_Click(System.Object sender, System.EventArgs e)
{
System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName("notepad");
foreach(System.Diagnostics.Process p in ps)
{
IntPtr editWnd = FindWindowEx(p.MainWindowHandle, IntPtr.Zero, "Edit", "");
string sTemp = GetText(editWnd);
Console.WriteLine(p.MainWindowTitle);
Console.WriteLine("------------------------------");
Console.WriteLine(sTemp);
Console.WriteLine("------------------------------");
Console.WriteLine("");
}
}
private string GetText(IntPtr hWnd)
{
int textLength = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1;
System.Text.StringBuilder sb = new System.Text.StringBuilder(textLength);
if (textLength > 0)
{
SendMessage(hWnd, WM_GETTEXT, textLength, sb);
}
return sb.ToString();
}
}
This approach is specific to Notepad (it's not a generic approach to any application). We're using FindWindowEx() to find a child window called "Edit", that is a direct child of the main application window. You can use tools like Spy++ to figure out the window hierarchy of an application to help solve problems like these. In situations where the target window is buried more deeply, or may be one of many windows of the same type at a particular level, you may need to use several other APIs to get a handle to the correct window. This is a complex topic and there are several other low level API approaches that can be used.
You could get the notepad++ source code and just write a plugin to get the text. Although notepad++ is written in C++ (you can still use visual studio).
You won't be able to do what you want with the standard windows notepad without hacking it or getting access to its source code.
The github for notepad++:
https://github.com/notepad-plus-plus/notepad-plus-plus

Sending keys to inactive application in C#/.NET [duplicate]

This question already has answers here:
Simulating Key Press C#
(8 answers)
Closed 4 years ago.
I have an application with combobox that contains names of currently running applications. As I understood from msdn library, SendKeys method can send keys only to active application. Is it somehow possible in .NET, to send keys also to inactive app? Or at least in WinAPI ?
You can use the SendMessage() API function to send keystrokes to an inactive window.
With C# <3 is everthing possible :D
No need to be active window, as u wished.
Also here a usefull list of Virtual Key Codes
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern bool PostMessage(int hWnd, uint Msg, int wParam, int lParam);
private void button1_Click(object sender, EventArgs e)
{
const int WM_SYSKEYDOWN = 0x0104;
const int VK_KEY_A = 0x41;
IntPtr WindowToFind = FindWindow(null, "Window Name");
//In ur case u have to write a code that translates the combobox into Virtual Key Codes. Will take time but it shouls be easy
PostMessage(WindowToFind, WM_SYSKEYDOWN, VK_KEY_A, 0);
//PostMessage(WindowToFind, WM_SYSKEYDOWN, ((int)Keys.NumPad7), 0);
}

Categories