0

I have a c# windows forms application framework 2.0

I want to be able to pass a command from another process or from command line to my windows forms application while my application is running. How can I send and how can I receive?

I know it can be done thought IPC but I dont want to go there just yet as this passing the argument feature will be rarely used and I am trying make minimal changes in the windows forms application as possible.

edit: Right now the I run windows forms application by double-clicking icon..Can I make it run from command line as a process (console application???) and send commands from command-line?

Edit: Further clarification: The command is entered by user.

bluish
  • 26,356
  • 27
  • 122
  • 180
bsobaid
  • 955
  • 1
  • 16
  • 36

5 Answers5

7

You can't pass arguments to an already-running program.

The standard method for doing this, as you mentioned, is starting a new instance to receive the arguments, detecting the already-running instance, and sending it commands via IPC.

As mentioned in the comments for some of the other answers, it is possible to have an application continually reading data from the command line. This is called the Standard Input stream, and is available in .NET via the Process.StandardInput class, documented here. Likewise, applications also have standard output and standard error streams.

Standard input can be leveraged from other applications, but ultimately that comes down to implementing a form of IPC.

Chris Shain
  • 50,833
  • 6
  • 93
  • 125
3

You can use the processes standard input stream as an alternative, or a named pipe, memory mapped file, etc.

There are lots of ways for two programs to share data or talk to each other.

You cannot specify/change command line parameters after the program has already started.

Update:

so I see many C++ application running from command-line and user keeps passing commands from there.

They are doing one of the options that I've listed here (or something similar that I haven't listed; there are a LOT of ways for different programs to talk to each other).

Is there a way to do the same with a c# windows forms application?

All of the above should work just in a windows forms application. Some may be easier than others, but they're all possible.

or I need to make it a console application and then somehow launch the UI part of it?

well, that's actually what's already happening; it's just all behind the scenes. Your forms app will still have a standard input; it can be launched from a shell; it can be given command line arguments; it can access pipes, files, sockets, etc.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • so I see many C++ application running from command-line and user keeps passing commands from there. Is there a way to do the same with a c# windows forms application? or I need to make it a console application and then somehow launch the UI part of it? – bsobaid Feb 16 '12 at 17:23
  • How do you know those c++ apps are not using IPC? – recursive Feb 16 '12 at 17:26
  • no, its not between application. It is the same command line window that starts the application and when you start it does'nt go back to normal prompt but stay in that mode and then user can pass in command. – bsobaid Feb 16 '12 at 17:32
  • It sounds like those applications are using standard input. Here is the documentation for the equivalent feature in .NET: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardinput.aspx – Chris Shain Feb 16 '12 at 17:34
  • @bsobaid that's using the standard input stream, it's not changing command line parameters. You can use that same stream yourself (whether explicitly in a shell, or behind the scenes by redirecting standard input). – Servy Feb 16 '12 at 17:35
  • @bsobaid, Are talking about simple console application (i.e. similar to built in Windows FTP client)? Such applications that simply read a command, executes it and repeat read/execute cycle till command="quit" (or simialr completition condition including Ctrl+c). – Alexei Levenkov Feb 16 '12 at 17:48
  • Actually, I just want user to enter a command to my windows forms application while it is running, without using its GUI. Think of a situation when UI becomes unavailable due to some error while other worker threads are still working. The inputstream allow me to send a command, but how do I receive it in my windows forms application? – bsobaid Feb 16 '12 at 20:26
  • @bsobaid you would need to specifically listen for messages in your forms app, using whatever medium you decide to use. Just keep in mind that if the entire premise is that the forms app has frozen, you may or may not be able to actually get any useful information out of it. The mechanism listening for other commands could end up being frozen as well, or you would be unable to access the UI thread (so yo don't freeze) which may mean not being able to give useful responses. As for actually how, just spin up a new thread (so you don't freeze) and call Console.ReadLine(). – Servy Feb 16 '12 at 20:32
1

Uhm, when your application starts up, let it see if this application is already running, if it is, then just take arguments and store that information into cache folder and exit second instance of your application.

First instance of your application should be monitoring changes in that folder and if anything changes, fetch that data and use it.

And please don't tell me it's too hacky or "unefficent" because this simply gets things done...no need to do some overly-complicated stuff.

Ardi Vaba
  • 179
  • 1
  • 4
  • 10
  • 1
    +1. This is not "hacky", it is just one of many ways to let "service"/"demon" kind of application to know that there is new work to be done. This approach works for cases where one does not care about easy confirmation of "your job is accepted". Another similar approach is to have queue of tasks in a database. – Alexei Levenkov Feb 16 '12 at 17:44
1

I basically started a new TCP link between my windows forms application and client application.

My windows application becomes a socket server and client as client, so whenever user wants to send in a command he can establish the connection and send it in.

Thanks for all the valuable input...I did learn a few things.

bsobaid
  • 955
  • 1
  • 16
  • 36
0

No matter what you do, you're going to have to make some changes in your Windows Forms app, I think, though you might be able to do some magic by sending win32 messages to it via the win32 SendMessage()/PostMessage() functions. That would work as long as its a message your winforms app is expecting.

You'll be making friends with the interop stuff in the process. Some links for using win32 messages as an IPC mechanism:

Alternatively, use System.IO.Pipes.

The first instance that starts is the "server". It should create a named pipe by creating an instance of NamedPipeServerStream and listen on it.

Anybody that wants to talk to the server -- whether its other instances of your app or a command line app, etc., needs to create an instance of NamedPipeClientStream and connect to it.

Here's an example: http://www.switchonthecode.com/tutorials/dotnet-35-adds-named-pipes-support

Your win32 app will need to monitor the server pipe to handle inbound message on the pipe.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135