Dynamically passing and using data to a WPF application without restarting it - c#

It's my first post on StackOverflow, so please be patient with me :)
I'm looking out for a way to pass a value to an already running application. The application should be able to accept this value and use it for further operations during its lifetime. I'd prefer not to logoff/restart the application in order to use the updated value.
The scenario would be something like this:
The application uses MachineName to initialize and populate some objects while it is being instantiated. Once it is up and running, I would like to pass a different workstation name to the application (possibly from command line) and the application should be able to use this MachineName and use it further down the line. I dont mind if I have perform same operations again to initialize the required objects with new MachineName name.
The application in question is a WPF app with C#. It's also using some WCF services as well. I was thinking to use a common registry key to store the workstation name and this registry key needs to be used/updated in the application. So it should be the first point of contact. But I'm not sure if this is a better approach. Any ideas please?

It's pretty easy to watch a file on disk using a FileSystemWatcher. When your app gets a change notification, re-read the contents of the file and update your app state.

The application listen to a socket port or watch a shared file when it starts up, if the application is called again with parameter, just open the socket port or write the command to the file, the first application can do the re-initialization .

First off, I think you might be over-complicating things a bit. If all you need to do is give your application a new string "MachineName", then you have several options (this is certainly not all of your options, just a few to think about):
Since this is a WPF application, we can assume some user is interacting with it...otherwise it may as well just be a console app. If this is the case, create a view giving the user the ability to change the MachineName. Perhaps a ComboBox listing all available MachineNames and a button to begin the re-initialization you need.
You apparently already have the plumbing in place for service calls. You could have your application act as both a client AND a service, allowing you to remotely (read: outside of this application) update your MachineName.
You can set this application up to monitor a specific directory or file (as pointed out by #jlew) and when some change occurs to that file, your application will read the change (the new MachineName) and begin it's re-initialization routine.
I don't know your full set of requirements, but I would probably set it up for both 1 and 2, which will give you a little more flexibility.

Related

best way to access a windows service via GUI

I'm curious about the best way for a C# gui to access the functions of a Windows Service, be it WCF or ServiceController or some other option.
I'll explain what I'm doing: on a regulated time interval the service will be zipping one hours worth of datafiles from location A and sending the zipped file to location B, this will be done in the background 24/7 or until the service is stopped by the user and runs even when no one is logged in (hence the need for service) I would like the user to be able to pull up a GUI program that will allow them several options:
1) change the location to zip from
2) change the location to zip to
3) manually start the zipping process for a DateTime range specified
Now most of the functions for zipping and timers is all stored within the service. SO im wondering if a ServiceController in the GUI program would allow me to send variables to/from the service (ie folderpath names as strings, various other data) or if I'll need to spend the time making a WCF and treat the GUI as the Client and the Windows service as a source.
It should be noted the GUI will likely recieve data from the service, but only to signify if it is currently busy zipping.
One option is to tave a WCF service embedded on your windows service. With this WCF you can control the behaviour without restarting the service.
But the best option IMO is to have this in a config file. You can add some keys, but you would have to restart the service when you update the config.
In this case you can try a workaround, as in this thread.
The config is a good place for this kind of detail, because it can be easily modified and, unlike a database, it will be always avaiable.
I don't fully understand what you're trying to say, but you define what the interface to your service is when you make it. If the operations you define take in variables, then you can pass data from your application to the service.
From what you described, just make opertaions in the service to do those 3 things you listed then call those from a button click in your UI code.
WCF would be fine for this here's a basic introduction to it http://msdn.microsoft.com/en-us/library/bb332338.aspx.

How to make a process fire an event in another process in c#/.net?

How to make process-1 able to fire an event in process-2, and send along few argument, to signal the 2nd process to do a specific action, and optionally receive a reply?
It is possible to do this using the filesystem, there could be a file, where process-1 dumps some commands/querys, and process-2 would be constantly reading from that file, but, this solution is not nice.
Any other way to do it?
(I know that its easy in VB.net to fire an event in a running process whenever a new process is started, IF the "single instance" is enabled in the project properties)
You can use named EventWaitHandle to achieve cross-process synchronization.
This article seems to do what you are used to with vb.net single instance (and it seems still a viable option).
In short it seems that there are three approaches to accomplishing single instance like solutions:
Use a Mutex
Cycle through the process list to see if a process with the same name is already running
Use the Visual Basic system for single instance apps (which you can access from C#)
If by "process" you mean "app-domain", it's fairly easy to set up eventing between the two. In fact if you have two classes in two separate app-domains (where each class has MarshalByRefObject as a base class), then .net will automatically set up a remoting structure that will make events appear to behave as they would in a single app-domain. (Example here: http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject.aspx)
The key here though is 'appear'. 'App-domain' and 'process' separation are intended to keep resources isolated on purpose. To access anything outside of your process you really need help from the operating system, like a shared file or internet connection or named pipes - something to that effect. But .net concepts like events don't exist outside of your space in the runtime.
In other words, you'd have to use something like Named-Pipes (http://msdn.microsoft.com/en-us/library/system.io.pipes.namedpipeserverstream.aspx) if both processes are on the same machine, TCPClient/TCPListener (http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx) if communicating across multiple systems, or WCF if you need something more heavy duty.
If you'd like to see a specific example of one of these technologies in practice, I can write one up for you, btw.

Passing Information Between Applications in C#

All. Firstly I am aware of the question Send data back to .exe from dll, however the answers there leave too many open ends for me and as I have no experience of what I am attempting I feel a new question is warranted.
I have an existing C# [All WinForms here] app that heavily relies on SQL. We have been asked (by clients) to provide an SQL Editor and library that can be used to develop and test SQL, but that can also be used to paste directly back in to the main application. The new SQLEditor is a multi-threaded application that parses and executes TSQL. I now have some things to consider; what is the best way to launch this second application from the main application::
Make the second app into a DLL and load into the main project, call the second app as a new form (SqlEditor sqlEd = new SqlEditor() etc.)? What are the implication in terms of thread bombardment, would I need [STAThread] - as I want both multithreaded apps to be available and active at the same time.
To launch as a separate .exe from the main application?
Depending on you advice; in either of the above cases - what is the best way I can pass information back to the main application from a click event in the second application whilst they are still both running and active [WCF, ApplicationDomains etc.]? Would the Observer design pattern come in to play here?
To make this question a little more appealing, here is the SQL Editor:
I plan to have a button which pastes the selected SQL back into the main application.
I am also aware that there are multiple questions here - which I apologise for. Thanks very much for your time.
If you need a simple way to do an outproc communication of two WinForms applications, then why don't you use the Clipboard with a custom format?
In the source application:
// copy the data to the clipboard in a custom format
Clipboard.SetData( "custom", "foo" );
In the destination application, create a timer to peek the clipboard:
private void timer1_Tick( object sender, EventArgs e )
{
// peek the data of a custom type
object o = Clipboard.GetData( "custom" );
if ( o != null )
{
// do whatever you want with the data
textBox1.Text = o.ToString();
// clear the clipboard
Clipboard.Clear();
}
}
This should fit your needs and it's still really simple as it doesn't require any heavyweight outproc communication mechanisms.
Another way of accomplishing intra-app communication is with the use of Windows messages. You define a global windows message id and use Windows API calls such as SendMessage and PostMessage.
Here's a simple article that explains how:
Ryan Farley's article "Communication between applications via Windows Messages"
This is in effect the observer pattern, receiving all the Windows messages being directed at the current Window and picking out the one you're listening out for.
In my experience this is definitely less flaky than the clipboard approach.
You have multiple choices for IPC(Inter Process Communication) such as:
Mailslot, NamedPipe, Memory Mapped File, Socket, Windows Messaging, COM objects, Remoting, WCF...
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365574(v=vs.85).aspx
http://en.wikipedia.org/wiki/Inter-process_communication
Some of them provide two-way communication, some needs considaration about system security(antivirus & firewall restrictions, you need to add the application as an exception in their settings).
Sending message through WM_COPYDATA can be done just by SendMessage, PostMessage is not supported, it means that the communication is sync.
Using outproc singleton COM object is another way, its not as simple as the other ways and both app. must be run on the same security context to access the same COM object.
Launching a separate application can coz some restrictions in communication methods or types of data you can pass, but separation of them will also protect them from their failures(App. crash will not close the other one).
If the two parts are always run on the same PC, using one of them as dll[inproc] is simpler. Using other techniques such as Socket, Remoting, WCF will provide you with more flexibility for communication, i.e. the two parts can run in different PCs with minor modifications...

Windows Service Vs Simple Program

Let me give a back ground for everybody before I go to my problem. My company hosts website for many clients, my company also contracts some of the work to another company.
So when we first set up a website with all the informations to our clients, we pass that information to the other company we contracted and three of us have the same data. Problem is once the site is up and running, our clients will change some data and when ever they do that we should be able to update our contracted company.
The way we transfer data to the contracted company is by using a web service (httppost, xml data). Now my question is what it the best way to write a program which sends updated data to the contracted company everytime our clients change some data.
1) Write a windows service having a timer inside my code where every 30min or so connects to the database and find all changes and send it to the contracted company
2) Write the same code as #1 (with out the timer in it) but this time make it a simple program and let windows scheduler wake it every 30min
3) Any other suggestion you may have
Techenologies available for me are VS 2008, SQLServer 2005
Scheduled task is the way to go. Jon wrote up a good summary of why services are not well suited for this sort of thing: http://weblogs.asp.net/jgalloway/archive/2005/10/24/428303.aspx
A service is easy to create and install and is more "professional" feeling so why not go that way? Using a non-service EXE would also work of course and would be slightly easier to get running (permissions, etc.) but I think the difference in setup between the two is nearly negligible.
One possible solution would be to add a timestamp column to your data tables.
Once this is done, you can have one entry in each table that has the last collected time by your contracted company. They can pull all records since that last time and update their records accordingly.
A Windows Service is more self contained, and you can easily configure it to start up automatically when the OS is starting up. You might also need to create additional configuration options, as well as some way to trigger the synchronization immediately.
It will also give you more room to grow your functionality for the service in the future.
A standalone app should be easier to develop though, however you are reliant on the windows scheduler to execute the task always. My experience has been that it is easier to mess up things with the windows scheduler and have it not run, for example in cases where you reboot the OS but no user has logged in.
If you want a more professional approach go with the service, even though it might mean a little bit more work.
A windows service makes more sense in this case. Think about what happens after your server is restarted:
With a Windows Application you need to have someone restart the application, or manually copy a shortcut to the startup folder to make sure the application gets launched
OR,
With a Windows Service you set it to start automatically and forget about it. When the machine reboots your service starts up and continues processing.
One more consideration, what happens when there is an error? A Windows application would likely show an error dialog and wait for input before continuing; whereas a service would log the error in the event log and carry on.

How to query a variable in another running application in c#?

I have an app that, when launched, checks for duplicate processes of itself.
That part I have right - but what I need is to check a state variable in the original running process in order to run some logic.
So: how do I make a variable (e.g. bool) available publicly to other applications so they can query it?
There are a bunch of ways to do this. A very primative way would be to read/write from a file. The old win32 way would be to use PostMessage. The more .NET way would be to use remoting or WCF and Named Pipes.
.NET 4 is also getting support for Memory Mapped files.
Here is a pretty thorough looking artcile describing a few different approaches including support for Memory Mapped files outside of .NET 4
http://www.codeproject.com/KB/threads/csthreadmsg.aspx
The easiest: Create a file, and write something in it.
More advanced, and when done correctly more robust, is using WCF, you use named pipes to setup some communication channel on the local computer only.
If you're using a Mutex to check whether another process is running (you should be) you could use another Mutex whose locked state would be the boolean flag you're looking.
The standard way of doing this is to use the Windows API to create and lock a mutex. The first app to open will create and lock the mutex. Any subsequent executions of the app will not be able to get it and can then shutdown.

Categories