in my application I've registered a file type (.asm) with my application (it's a tabbed notepad application), and when those files are double-clicked they open with my application through the arguments passed when it's loaded:
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Main(args));
}
Now the problem is, while this does work, if one instance of my application is already running, whenever a file is opened, a new instance of it is created rather than a new tab being opened in the current instance which I don't want. So I thought of checking if the program is already running, and if it is then I would call a separate function in the main form to load that document instead. But the problem is, I don't know how you call a function in Main.cs from Program.cs, how do we do that?
It's more complicated than just calling a function in Main.cs from Program.cs because the OS will launch a second process for you at the time you double-click your registered files. You need some way to find out if there is another existing process running already and then communicate with that existing process, if there is one.
Fortunately, there is a class in the .NET Framework that already does all of the hard work for you:
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
See this blog for a complete example:
http://windowsclient.net/blogs/suryahg/archive/2008/08/20/use-of-microsoft-visualbasic-applicationservices-part-2.aspx
The technique in this question might help:
C# : how to - single instance application that accepts new parameters?
Related
When start another process using Process() class, newly created process is still associated with the one invoked the start command, which is in turn causing issues with monitoring software or even within the stirted application itself.
So the question is if it is possible to start an external binary detachad from the caller, as a fully standalone instance? (Like started directly)
Update:
There are some processes expected to be a subprocesses of a specific process.
Like IE usually a subprocess of explorer.exe.
But started from C# app.exe with Process().start(#"path/to/iexplere.exe") it is a subprocess of app.exe
So is it possible to attach it to expected explorer.exe?
The most common approach is to start an intermediate process (let's call it the child) that in turn starts the binary you want to detach (the grandchild).
The intermediate process is then terminated, leaving the grandchild without direct parents.
You are not showing any code, so we can't help you more than that. You can start from here.
I've found a workaround for it.
It includes two applications. Lets call them handle.exe and detacher.exe
handle code:
static void Main(string[] args)
{
Process.Start(AppDomain.CurrentDomain.BaseDirectory + "detacher.exe");
Console.ReadLine();
}
detacher code:
static void Main(string[] args)
{
Process.Start("IExplore.exe", "google.com");
}
handle starts detacher and proceeds.
detacher starts IE and terminates.
IE drops to process root and proceeds.
Looking how to run the program.cs file from a winform as I'm trying to run it, hide it and display the text in the textbox but I cannot find a way to run the console separately once the winform has started up!
A .cs file is just plaintext as far as I'm aware - You probably need to to actually be executable - From there you can use IPC to communicate between the two processes.
If you have somehow made the program.cs run (Black magic?) you could also get one process to write to a text file, then get the "winform" process to read from it (And then delete it!).
You might try elaborating on your problem, method and environment in your question - There's not a lot to work off here.
Make a console application and add a WinForm to do. Show the winform with .ShowDialog() and you will have both the console and the winform showing at the same time.
class Program
{
static void Main(string[] args)
{
var dlg = new Form1();
dlg.ShowDialog();
}
}
The issue I'm having is trying to find the run order for a number of classes in a project. There is no explicit main and I have looked in obj/debug and found nothing which might have been generated at compile time. Have you any ideas where I might find something. Also I cannot find any xaml files either. It's a console function.
This is a quick way to find the entry point (if there is one):
Without any specific source file open, press F11 to start the debugger at the first line. This should make your entry point obvious.
Note that if this is a Console Application like you said, there must be a static main() method.
Here is the documentation for Main():
The Main method is the entry point of a C# console application or windows application. (Libraries and services do not require a Main method as an entry point.). When the application is started, the Main method is the first method that is invoked.
If you check the project properties, under "Application", there is a "Startup object" listed. This should tell you the entry point to the application, which is the type which contains the Main method that is actually being used.
If it's a console application then you will usually find the Main method in the auto-generated Program.cs file.
If there is no main method, the project is a class library.
Other than #Gray's answer, you could also Ctrl+F for Main.
I'm creating a (C#) program that downloads binaries using NZB files, there may only be one instance of my application running at any time.
So when a user doubleclicks an .nzb-file and my program is not running, it should start and process it (easy, file registration).
Now if my program is already running, I do NOT want to launch a second instance - I want the already-running instance to pick up the specified file.
Making my app single-instance can be done using the Visual Basic DLL with the .IsSingleInstance trick, but I don't want to go there.
The right way seems to be to use a mutex to ensure my app is single-instance,
but now I'm stuck on how to pass the specified parameter (the .nzb file) to the already-running instance.
Help would be appreciated ! :-)
Try this: Your main program creates a named pipe or other interprocess communication facility and listens on it. You create a separate small program that, when run with an NZB file as a parameter, opens the pipe, feeds the file info into it, and exits. Your main program then processes the new file and downloads it.
Why not have one program that adds the file to a queue, and then kicks off the downloading program if it is not already running. That downloading program watches the queue, which is just a file that you append download file names to.
Look at the InitialInstanceActivator at the Genghis project
Use an IPC (inter process communication) mechanism such as .net remoting
When you double-click on a Word document, Word is automatically run and the document is loaded.
What steps are needed to do the same thing with my C# application?
In other words, assume my application uses ".XYZ" data files. I know how to tell Windows to start my application when a .XYZ data file is double clicked. But how do I find out within my application what data file was chosen so I can load it?
Granted this is a VB.NET solution, but this article has details on how to create the file association for your application in the registry and how to retrieve the command arguments when your application is fired up to do the proper file handling.
It looks easy enough to port over to C#.
The arguments should contain the path to the data file.
You can tweak this behavior and pass additional arguments. Look at the example in this image. Here the file path is passed with %1.
Quicktime File Association Dialog
I think what you are looking for is command-line arguments. If you look at the Open action for .doc for example you'll probably see something like this 'word.exe %1'. Windows will take the name of the file and substitute it in for %1 and then execute the command 'word.exe whatever.doc'. Then from within the application you can see what was passed as an argument into the program see this MSDN article for more details.
I believe it is just a command-line argument that gets passed into your app. Then you can read it with Environment.GetCommandLineArgs. I know that is the case if you drag-and-drop a file onto your app. I have not done what you are describing myself but I assume it works the same way.
I did this in a project I was working on awhile ago and don't have the source code handy, but I believe it really came down to this:
//program.cs
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if (args.Length > 0)
{
//launch same form as normal or different
Application.Run(new Form1(args));
}
else
{
Application.Run(new Form1());
}
}
args is empty when the application is normally started, but when you've properly linked in the association to your .xyz file, when one of those files is selected, your application will be launched with the file location as the first element of the string[]. Certainly either in program.cs or your launch form, I would add validation, but at the base level I believe this is what you need to do.