Programatically paste text into text box in another application - c#

I want to be able to paste the results from my application to another application. Been Googling and all I can find is the ApplicationCommands.Paste. That will paste it into my application not another application.
Background: My application needs to interact with a very old application. This application is not being developed and DOES NOT have any API calls. Meaning any answers like "Link your application via DLLs" will only be excepted if it also includes a time machine :P So the solution is to simple paste results from my app to the old application.
For workflow reasons the client wants my Application to disappear and automatically paste the results into an open text box in (if it fails then manually pasting the results in).
Hiding the window is simple, but how do I find current active application and then paste it in? Is this even possible? Also note this application is NOT .NET (VB 6 if I am correct).

You can bring up the other app and send a key combination... something like:
[DllImport ("User32.dll")]
static extern int SetForegroundWindow(IntPtr hwnd);
public static void PasteToApplication(string appName)
{
var proc = Process.GetProcessesByName(appName).FirstOrDefault();
if(proc != null)
{
var handle = proc.MainWindowHandle;
SetForegroundWindow(handle);
SendKeys.SendWait("^v");
}
}
This should bring up the other app's window and send a ctrl-v command. With a bit of experimentation, you could find out the exact handle of the control you want to send the paste to, and set focus on it aswell

Related

AppServiceBridge without console window

I'm playing with Microsoft's UWP AppServiceBridgeSample (here).
It is working well, but I would like to get rid of the console window of the BackgroundProcess application. The reason for this is that my BackgroundProcess starts another Win32 desktop application and works only as a mediator, so I don't want to disturb users with a console window. (Yes, it can be minimized, but I would rather not show it at all).
I have tried to hide it using the API mentioned here, but with no luck, the console window is still visible. Neither did switching the project's output type from Console Application to Windows Application.work.
Another thing I have tried was to create other BackgroundProcess project as a Windows application. It runs fine until I call AppServiceConnection.OpenAsync(), which causes the BackgroundProcess application to exitstrong text, thus the connection to UWA is not available.
static async void ThreadProc()
{
try
{
AppServiceConnection connection = new AppServiceConnection();
connection.AppServiceName = "CommunicationService";
connection.PackageFamilyName = Windows.ApplicationModel.Package.Current.Id.FamilyName;
connection.RequestReceived += Connection_RequestReceived;
AppServiceConnectionStatus status = await connection.OpenAsync();
//status check etc. ...
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
It seems that opening the AppService connection is only possible from a console app.
So here are my two questions:
Is it, by any chance, even possible to hide the background process' console window?
Can I use the background process as a Windows application, without AppServiceConnection failing during OpenAsync calls?
Re 1: Go into the project settings and change the output type from Console to Windows app. Also make sure the Main() function doesn't exit until you are done with the background process. Here is a better sample that shows this with a Windows Application:
https://stefanwick.com/2017/05/26/uwp-calling-office-interop-apis/
Re 2: AppServiceConnection works the same way from a windowed application as well. Make sure you add the right reference to the Windows.winmd to be able to build. If you have trouble with that, please post a specific question with details of the problem you are seeing

Send username and password to another application

I would like to send a user name and a password to another application, and process the input.
so I have Application A which has a window that requires a username and a password.
and we have Aplication B that is running. Application B needs to search for application A, login window, and send the user name to a textbox in it and the password, and then process those unputs through the Ok button.
Are there any libraries that can handle those sorts of requirements?
Any help weather it be website or dll references or examples would be great
NOTE:-
APPLICATION A is not something I built, or have access to its code or anything, I can start it, thats about it.
here is the process just to make things clear since some are confused:-
Application B is an EXE application, when clicked, it does some logic, then it starts Application A.
As soon as Application A starts, the user will prompted with a dialog box to enter user name, and password This is not something I made, it is what the application does. My question is can I access this dialog window, and send inputs to it.
FORM CODE
public partial class Form1 : Form {
[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hWnd);
public Form1() {
InitializeComponent();
var process = new ProcessStartInfo(#"arcmap.exe");
var pr=Process.Start(process);
SetForegroundWindow(pr.Handle);
SendKeys.Send("ne{TAB}ne{ENTER}");
}
}
}
This doesn't sound like a proper design strategy to me. Why not merging the two applications to one and passing the requested values between different application forms?
If for some reason you need to use two different applications, simply open application B AFTER the user has entered his login credentials in application A, and pass those values as parameters to your second app.
You can also consider using a TCP class in order to virtually connect the two of your apps using sockets.
You'll need to start Arcmap (this is a fairly easy task using Process.Start(string path);, then give it some time to boot using Thread.Sleep(int miliseconds), and then it gets tricky.
You'd have to get the Arcmap process (probably by name) and set it as foreground window by importing this method:
[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hWnd);
And then calling it this way:
Process process = Process.GetProcessesByName("arcmapProcessName").FirstOrDefault();
SetForegroundWindow(process);
And later you just send keys using
SendKeys.Send("login{TAB}password{ENTER}");
Then you would have to reference the SendInput function to programatically inject keyboard keypresses into the input stream. Perhaps, since it's a lot of hassle to reinvent the wheel and you're asking for an external library anyway, you could use C# Input Simulator.

SQL Agent Job running .NET C# WinForms application with a WebBrowser control. Trying to send key strokes

As the title suggest, I have a .NET C# Winforms app with a WebBrowser control. I use it to download a (dynamically generated) Excel file from a website, and it is working just fine. I have to use a WebControl as per my employer request.
When I use a SQL Agent Job to run a SSIS package with an Execute Process Task to execute the app, it fails (as in the file is not downloaded). If I run the SSIS package it works, correctly. The difference is with the SQL Job the app window is not showing.
When the WebBrowser control shows the Open - Download - Close dialog, I send key strokes (Alt + S) to save the file and then close the dialog. When the SQL Job runs the app, the keystrokes never make it to the WebBroser.
I have tried sending keys using SendKeys.SendWait, and also using User32 dll to get the dialogs and buttons handles and then SendMessage/PostMessage (tried both) to send the key strokes. Both methods work correctly as an exe, and as a SSIS package. And both methods fail when running the SQL Job.
I also have tried overriding the download manager as suggested here without success. To be honest I don't know what to do to get the dynamically generated Excel file the app have to download when the execution reach the overrided Download method. The link I get when debugging the Download method is not the link to the file.
/// <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;
pmk.GetDisplayName(pbc, null, out name);
if (!string.IsNullOrEmpty(name))
{
Uri url;
if (Uri.TryCreate(name, UriKind.Absolute, out url))
{
if ( FileDownloading != null )
{
FileDownloading(this, new FileDownloadEventArgs(url));
}
return Constants.S_OK;
}
}
return 1;
}
This is the Response Header when I click the button to download the file:
Content-Disposition: attachment; filename="file.xlsx"
Content-Transfer-Encoding: binary
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
I can provide with the app code if requested.
Any help would be really appreciated. Excuse my poor english.
Regards
This sounds silly. Why do you have to use a web control to download and immediately save the webpage? Since SQL agent is running as a service you'll give yourself a headache trying to work with a windows forms application.
I'd either create a separate non interactive console application which does the download and saving, or if reusability is the motivation- split the application in two: one exe with the windows form, and another exe with the download logic. The first exe can reference the other exe to access its public classes.

How to close a WPF application running in system tray from a C# console application?

I'm developing an application which has 2 parts:
1) A WPF application which runs from the system tray. It does have a GUI window, which can be brought up by right-clicking the sys-tray icon & choosing an option on the context menu, but it is not needed very frequently & the app will run from the sys-tray most of the time. Moreover, I've changed the Closing() event of the MainWindow, so as to minimize the app, if the user tries to close it.
2) A console application which runs without displaying a console & its purpose is to poll for launch/close of another application. As soon as the other application is launched/closed, the console application launches/closes the WPF application too. (Please don't tell me to do this using a Windows Service. I've already explored the route before. It doesn't work for me due to several reasons, which I won't enlist here).
PROBLEM: I am not able to close the WPF application from the console application. What I'm doing is as follows. First I obtain the process for my WPF application:
Process AppProcess = Process.GetProcessById((int)AppID);
After this I've tried a lot of options as follows:
1) Killing the process: AppProcess.Kill();
This is the only one which worked, but is very unelegant. It also leaves the SysTray icon undisposed, so it is not acceptable.
2) AppProcess.Close();
Doesn't work at all & I don't know why.
3) AppProcess.Dispose();
Doesn't work at all & I don't know why.
4) AppProcess.CloseMainWindow();
This only works if the user has kept the GUI of the WPF app opened, which is very rarely the case as I mentioned before. So, normally this also doesn't work. (You might say that I've hacked the Closing() event to prevent closing the window. Don't worry I've taken appropriate care to handle that. I've provided other measures to close the app. There is a boolean variable which decides whether the Closing action is to be cancelled or not.)
5) Passing custom/standard message to the WPF Application's main window.
This also works only if the main window (GUI) of the WPF app is open, else it doesn't receive the message.
So, all in all, no method is working. I need a reliable method to close the WPF app gracefully from the console app. Please suggest something.
The current way I'm doing it is as follows:
In the Console App:
const uint WM_CUSTOMCLOSE = 0xFE;
IntPtr hWnd = AppProcess.MainWindowHandle;
SendMessage(hWnd, WM_CUSTOMCLOSE, 0, 0);
In the WPF app:
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if(msg == 0xFE)
{
ExitFlag = true; //Exitflag is checked later to decide whether closing is to be cancelled.
this.Close();
}
return IntPtr.Zero;
}
Use IPC as JeffRSon suggested. MSMQ is a very easy and effective way when two processes are on the same machine.
Define a queue of your WPF application and when it starts, no matter showing UI or not, let it listen the queue. Console application can send a message to the queue with closing application message. You have to define the data contract. You can refer to:
http://www.codeproject.com/Articles/3944/Programming-MSMQ-in-NET-Part-1
Ok, I found a way to close the WPF app. The reason it wasn't receiving the message was that for some reason, AppProcess.MainWindowHandle was not giving the handle of the main window of the WPF app, when the WPF app ran from the system tray.
So, instead I'm using the user32.dll:FindWindow() method found in the Win32 APIs to find the main window of the WPF app. After that when I pass my custom message to it, the WPF app shuts down gracefully.

How to run a .NET console application in the background

I have a console application written in C# that is scheduled to run every 15 minutes or so using the built-in Windows Task Scheduler.
Every time it runs, the black console box pops up for the duration of its execution and then closes. I am not writing anything to the console. Is there a way to make this run in the background?
Project > Properties> Application tab > change Output type to "Windows application".
No more console window.
Easy!
It seems hard to believe, but it works as a charm. I have used this for some setup projects, when you want to perform custom tasks with no signs of it.
Create the project as a Windows application project (this is the hard part).
Never make calls to any form. Just keep on in exactly as in your console application
class Program
{
static void Main(string[] args)
{
// Just don't call Application.Run(new frmMain(args));
// ... your code
}
}
This is because windows application projects are no really different than console, except because of the first form and references.
It is totally hidden execution. Try it!
You can use the Windows API to minimize the console box. Otherwise you can make it a Windows EXE file that does not actually load a form and call System.Windows.Forms.Application.Run().
Code to minimize the console:
[DllImport( "user32.dll" )]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
public const int SW_SHOWMINIMIZED = 2;
IntPtr winHandle = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
ShowWindow(winHandle, SW_SHOWMINIMIZED);
What about implementing the app into a windows service? You can set the interval to 15 mins and run the operation in the timer_tick.
If you already have a Windows Console app created you can simply change the Output type of your app to Windows Application.
Under your project:
Go to Properties > Application
Select "Windows Application" as the Output type.
This would be the least impact and you can keep your Windows Task Scheduler running the same task.
If it doesn't write anything to the console you could make it a service.
http://msdn.microsoft.com/en-us/library/9k985bc9%28VS.80%29.aspx
It will only show up if it's scheduled to run as the same user that's currently logged in. Create another user on the machine with a ridiculously long password, set it to be an Administrator (only if needed) and schedule the task to run as that user.
This is easy. Set the task to run under an account that is not your login account.

Categories

Resources