可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
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.
回答5:
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:
- http://www.codeproject.com/Articles/19740/Send-strings-to-another-application-by-using-Windo
- http://www.codeproject.com/Articles/137/Sending-a-message-to-the-Main-Frame-Window-of-Anot
- http://ryanfarley.com/blog/archive/2004/05/10/605.aspx
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.
回答6:
Any application have command line parameter - so if you just want to pass them once at startup - just do so.
Otherwise you want console application that shows forms - i.e. see how to run a winform from console application?.
Note: While having console and window at the same time is possible, user experience could be confising. Consider adding simple textbox "command" to your form to input commands. I.e. VisualStudio have several "command" windows as an example - "Immediate" where you can execute code agains running program, "searc"/"command" - go to search text box in toolbar (or Ctrl+/) and type >open .