So I have an application that has a special file type .rxml associated to it.
If the application is already running and I open one of these files, it opens a new instance of the application. Is there a way to make the file open in the same application instance?
Yes, roughly-speaking, a new instance of the application will be launched, detect the existing instance and pass information to it, e.g. the path to the new file to be opened. You have a few options for this task, including WCF and Remoting.
Related
(Sorry for my bad english)
Hi I have a problem.
I need to open the associated files already in my program while it is running.
If we take example visual studio, when I opened the ide and I double-click on a file example test.cs
Do not opening a new application,
But he added a tab with the new file.
And 'possible to do such a thing?
As you've observed, Windows Explorer will try to launch a new instance of your app when you double-click a file associated with your application. You can't change that. What you can do is have the new instance check whether an instance is already running and, if so, tell the running instance to load the file. There are lots of ways to establish this sort of communication. You could listen on a port, periodically check for a file in a particular location, etc. How to do it is up to you.
I created a wpf application that can create, write to, and read from a .txt document to store and persist data. Currently the application creates the text file within the solution folder, but what I would like to accomplish is the ability of the executable file to act as a stand-alone application that can spawn the text file somewhere on the user's computer, and continually persist and retrieve data from that file.
So, theoretically I could send a copy of the executable to a friend, they could open it and upon saving data a file would be spawned on their computer which would then be called whenever the application was run.
Right now what I had in mind for an answer is which folder I would need to use in this call within my application:
FileStream fs = new FileStream("ListOfTasks.txt", FileMode.OpenOrCreate);
StreamReader s = new StreamReader(fs);
Or otherwise, what other methods I could use to cause my executable to act as a stand-alone that can persist data without a database.
You don't want to be writing to the solution folder, since that will require administrative privileges on any Vista+ machine.
You might want to look into using the ProgramData folder, see this question for more information:
Write in "ProgramData" folder (W7 and Vista) .NET
This is an excellent resource for working out where you should be writing files, based on a few different scenarios:
Where should I put program data: http://blogs.msdn.com/b/cjacks/archive/2008/02/05/where-should-i-write-program-data-instead-of-program-files.aspx
My WPF app can open and edit single documents. I am looking for a tidy approach to allow multiple instances of my WPF app to run but to only allow a given document to be open in one instance of the app. If a user tries to open a document which is already opened in another instance, I need to pop up a dialog to tell them and allow them to switch to the other app instance if required.
Thanks
Dan
One approach is to attempt to take an exclusive lock on the file when you open it. When your other application instance attempts to open the file, an IOException will be raised. You can catch this exception and show a dialog to your user stating that the file is already opened in another application. This scenario should be covered anyway, as the file could be open in a different application that is not yours.
I want to open files, which are doubleclicked in Explorer, in the same instance of my .Net application, e.g. in a new tab. How can I do this?
For now each file starts new instance of my application. Many programs can open files in the same instance, for example, Opera and Notepad++, so there is an easy way for sure.
You may take a look at this post which illustrates a technique that could be used to have a single instance WinForms application.
Might be an easier way to do it but the way I've done it is that if an instance is started with a filename as a parameter then it checks if there are any other instances and if so passes on the filename to that instance and the close itself down.
In case you want to do the same, but in WPF rather than WinForms, the howto is explained here: What is the correct way to create a single-instance application?
Example using TCP-sockets:
http://pieterjan.pro/?a=Projecten_csharp_DrawIt.php
start TCPListener on the form
connect TCPClient in the main of the second instance
Send ActivationArguments through the TCP-connection to the form
Works for multiple files at once as well, and even for multiple files at the first time (when application not started yet)
The most important code blocks are:
The constructor of the MainForm (Hoofdscherm) where the server is started and the port number is written to a file. The first file is opened as well.
The Main-function (Program.cs) where the second, third, ... instance connects to the TcpListener in the first instance and sends the filename through the socket
The source code is available on the button "Broncode"
How would you open a file (that has a known file/app association in the registry) into a "running instance" of the application it's supposed to open in? An example would be, I have Excel open and I click on an XLS file.....the file opens up in the current Excel instance. I want to do this for a custom application...how does the eventing/messaging work that "tells" the current instance that it needs to open a file? Is there a "file watcher" that looks for a request to do so etc? Thanks..
What you want to do is inherit a class from WindowsFormsApplicationBase, setting the protected IsSingleInstance property to true:
// This should all be refactored to make it less tightly-coupled, obviously.
class MyWindowsApplicationBase : WindowsFormsApplicationBase
{
internal MyWindowsApplicationBase() : base()
{
// This is a single instance application.
this.IsSingleInstance = true;
// Set to the instance of your form to run.
this.MainForm = new MyForm();
}
}
The Main method of your app then looks like this:
// This should all be refactored to make it less tightly-coupled, obviously.
public static void Main(string args[])
{
// Process the args.
<process args here>
// Create the application base.
MyWindowsApplicationBase appBase = new MyWindowsApplicationBase();
// <1> Set the StartupNextInstance event handler.
appBase.StartupNextInstance = <event handler code>;
// Show the main form of the app.
appBase.Run(args);
}
Note the section marked <1>. You set this up with an event handler for the StartupNextInstanceEvent. This event is fired when the next instance of your app is fired when you have a single instance application (which you specified in the constructor of MyWindowsApplicationBase). The event handler will pass an EventArgs-derived class which will have the command line arguments which you can then process in the running instance of your app.
Then, all you have to do is set the file associations normally for the file types you want your app to process, and you are set.
Looks like what you are looking for is creating a single instance application. This can be done in C# by using WindowsFormsApplicationBase located in Microsoft.VisualBasic.dll
For details, take a look at:
http://www.hanselman.com/blog/TheWeeklySourceCode31SingleInstanceWinFormsAndMicrosoftVisualBasicdll.aspx
or search for WindowsFormsApplicationBase
The way I'd do it is like this:
First thing in the main method, check the process list for an existing instance of the application.
If found, send the filename/path to the already running instance using your favorite interprocess communication method (sending windows messages, remoting, wcf, etc.)
Close the new process that windows tried to start (since the existing instance already handled the file open operation
Example using TCP-sockets:
http://pieterjan.pro/?a=Projecten_csharp_DrawIt.php
start TCPListener on the form
connect TCPClient in the main of the second instance
Send ActivationArguments through the TCP-connection to the form
Works for multiple files at once as well, and even for multiple files at the first time (when application not started yet)
The most important code blocks are:
The constructor of the MainForm (Hoofdscherm) where the server is started and the port number is written to a file. The first file is opened as well.
The Main-function (Program.cs) where the second, third, ... instance connects to the TcpListener in the first instance and sends the filename through the socket
The source code is available on the button "Broncode"
Windows uses DDE for this purpose.
Dynamic Data Exchange (DDE) is a technology for communication between multiple applications under Microsoft Windows or OS/2.
Registry associations for word or office files usually have DDE commands in addition to the usual file association (to be executed if the app already is running).
So you can host a DDE server in your C# app to implement this functionality.