This question already has answers here:
What is the correct way to create a single-instance WPF application?
(39 answers)
Closed 7 years ago.
I've Created a Music Player using Visual Studio 2012 Windows Form C#. now I want the user to be able to play songs in windows explorer such as other players(Windows Media Player,Winamp,etc.) with my player.
I already found the way to File association!
but I need to prevent my application from running multiple instance(as WMP&... don't) and I want to get the songs Paths too to send them to my application(already started).
For example User Select 3 Songs in a directory in windows explorer & Press Enter so my application / and execute my AddFiles Function (add the supported files to playlist and ...)
I tried mutex it solves the first part(just single instance) but can't get arguments from it!
I also tried this but No chance :( it gave error!
** I already triedWhat is the correct way to create a single instance application? "Matt Davis" Answer and it makes my application to be single instance only and bring to front part was awesome but didn't send arguments to my running process so It couldn't solve my problem!
any Help would be in advance :)
UPDATE:
I don't understand while I haven't get my problem solved why experts close the question!? :| :/
UPDATE 2 (FOUND THE SOLUTION):
ok Finally I've got the solution :)
this link helped me to get paths of selected files in explorer by clicking on a context-menu item:
.NET Shell Extensions - Shell Context Menus
real easy :)
Hope this help others too!
I use this: https://code.msdn.microsoft.com/windowsapps/CSWinFormSingleInstanceApp-d1791628
It's single instance, and supports command line args. My program is started like this:
[STAThread]
static void Main(String [] args) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 mf = new Form1(); // your form
SingleInstanceAppStarter.Start(mf, StartNewInstance);
}
...
private static void StartNewInstance(object sender, StartupNextInstanceEventArgs e) {
String cmdArg = e.CommandLine[1]; // yes, 1 to get the first. not zero.
...
}
You'll also need this:
class SingleInstanceAppStarter
{
static SingleInstanceApp app = null;
public static void Start(Form f, StartupNextInstanceEventHandler handler)
{
if (app == null && f != null)
{
app = new SingleInstanceApp(f);
}
app.StartupNextInstance += handler;
app.Run(Environment.GetCommandLineArgs());
}
}
and this:
class SingleInstanceApp : WindowsFormsApplicationBase
{
public SingleInstanceApp() { }
public SingleInstanceApp(Form f)
{
base.IsSingleInstance = true;
this.MainForm = f;
}
}
Note that both of those classes use the Microsoft.VisualBasic.ApplicationServices assembly (You'll have to reference it).
Related
This question already has answers here:
Console application closes immediately after opening in visual studio
(5 answers)
Closed 6 years ago.
I have a little console application which outputs a single line. When I run the program from within a console instance I am able to see the result because the command pormpt reappers after completion of the program. But when I start the program from the "Run"-window ([Win]+[R]) the console window instantly disappears (because I have not built in a break and i don't want to build in a break unless it isn't launched by the commandline).
So how can I determine if the program was started from a command line or directly?
I don't think there a built-in way to find this out. However I think you could look up the parent process and use that as fairly good heuristic. A quick test shows that the parent process is "explorer" when started from Run (Win+R) or double clicking. It would probably be cmd or powershell any other time except when debugging in VS, then devenv will be the parent process. Obviously, if there are scenarios where other tools will start an instance of the process you may want to give a command line parameter to force a particular behavior.
You code would look something like this:
// Note: Adapted from Hans Passant's answer linked above.
private static string GetParentProcessName()
{
var myId = Process.GetCurrentProcess().Id;
var query = string.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", myId);
var search = new ManagementObjectSearcher("root\\CIMV2", query);
var queryObj = search.Get().OfType<ManagementBaseObject>().FirstOrDefault();
if (queryObj == null)
{
return null;
}
var parentId = (uint)queryObj["ParentProcessId"];
var parent = Process.GetProcessById((int)parentId);
return parent.ProcessName;
}
static void Main()
{
/*
Program code here.
*/
if (string.Equals(GetParentProcessName(), "explorer", StringComparison.InvariantCultureIgnoreCase))
{
Console.ReadLine();
}
}
I don't think there is any way to programmatically determine how the console application was started.
If you want the application to behave differently in these different situations then I would suggest using arguments e.g.
MyApp.exe /keepopen
code:
static int Main(string[] args)
{
// Test if argument was supplied:
if (args.Any(a => a == "/keepopen"))
{
System.Console.ReadLine();
}
}
If you want the console to stay open when running from Visual Studio I believe you can use Ctrl-F5 to start without debugging.
This question already has answers here:
How do I convert a .NET console application to a Winforms or WPF application
(2 answers)
Closed 8 years ago.
I want to do some changes here, I want to convert this application to winforms. And i want to store these output into a text file, How can I do it? please help
using System;
using System.Threading;
public static class Program
{
public static void Main()
{
// Create a Timer object that knows to call our TimerCallback
// method once every 2000 milliseconds.
Timer t = new Timer(TimerCallback, null, 0, 1000);
// Wait for the user to hit <Enter>
Console.ReadLine();
}
private static void TimerCallback(Object o)
{
// Display the date/time when this method got called.
Console.WriteLine(DateTime.Now);
// Force a garbage collection to occur for this demo.
GC.Collect();
}
}
Output of this application.
Source Stackoverflow
Go to application > and change is Application type to Winform and then point start up object at Sub Main
Right click on the solution and select "Add Reference"
Select System.Windows.Forms and hit OK
I use a component in my C # application it loads the DLL, an icon appeared in the windows tray, is there any way to hide the icon in tray using the command line or any exe with arguments?
Thanks.
From the command line IMHO its not possible unless the exe supports it, eg:
static void Main(string[] args)
{
if (args.Length > 0)
{
if (args[0] == "HideFromWindowsTray")
{
this.ShowInTaskBar = false;
}
}
You could possibly do it using other techniques, eg have a wrapper exe that launches a exe and sets its ShowInTaskBar form property to False. To get inspiration on how you can do this, see HawkEye - The .Net Runtime Object Editor
ps next to each answer is a holo checkbox, tick it to accept answer and you'll get points too.
I am working on a Windows application. I have created a help file (.chm) using a third party tool and I call it from the Windows application. The help file is invoked successfully when I click on Help menu item or press F1 for the application.
The problem I am facing is that if I click on the menu item again or press F1 (while the application is open and I have not closed the previous help file) it opens another instance of the help file.
Let me be clear by giving an example: I want it to be just like the "Solitaire" game. No matter how many times you press F1 or the Contents menu item it shows only one help window.
I want to do same thing like "Solitaire". I don't want multiple instances to be created.
I hope you understood my problem. Please let me know if my query is wrong.
I have posted my code below.
ProcessStartInfo info;
Process exeprocess;
The below code is in Help menuitem click event.
private void mnuContents_Click(object sender, EventArgs e)
{
string ApplicationPath=ConfigurationSettings.AppSettings["HelpFile"].ToString();
info = new ProcessStartInfo(ApplicationPath);
//Process.Start(info);
exeprocess = Process.Start(info);
}
One solution is:
Have your application create a system-wide resource (the example below uses a Win32 mutex)
Check the resource before you spawn the .chm (I imagine you're probably using ShellExec or some variant to spawn the help file.
Here's example code (in C++/Win32 code):
http://support.microsoft.com/kb/243953
Another, different approach is to see if any currently running processes match the one you would spawn. Here's example code for this approach:
http://www.dotnetperls.com/single-instance-windows-form
You have a Process object, so you should probably store it somewhere and check if it is still active the next time the help command is invoked. You could use Process.HasExited for that purpose. If it has exited, clean up the Process object by calling Dispose() and then launch a new instance, storing it away again. Repeat as needed.
Ok this is your block of code to start the CHM viewer:
private void mnuContents_Click(object sender, EventArgs e)
{
string ApplicationPath=ConfigurationSettings.AppSettings["HelpFile"].ToString();
info = new ProcessStartInfo(ApplicationPath);
//Process.Start(info);
exeprocess = Process.Start(info);
}
in exeprocess there is a property called Id. You need to keep track of that Id for the next time the user presses F1 or the menu key.
You need to do a check like
private void mnuContents_Click(object sender, EventArgs e)
{
if (Process.GetProcessById(self.previousId) != null) {
string ApplicationPath=ConfigurationSettings.AppSettings["HelpFile"].ToString();
info = new ProcessStartInfo(ApplicationPath);
//Process.Start(info);
exeprocess = Process.Start(info);
self.previousId = exeprocess.Id;
}
}
Something like that would work. If you want to get fancy, you can bring the already-running process to the foreground as well.
[DllImport("kernel32.dll")]
private static extern Int32 AllocConsole();
I can open cmd.exe with this command. But i can open only one console window and write in it. How can i open another one? Is any clean and fast solution for opening two console windows?
So you can do multiple console windows within one single C# windows app, but to do so you would have to have a few things. Process.start(), and command-line parameters.
If you do it this way you can have your app create another instance of itself, but with different command line parameters to have each part do different things.
Here is a simplistic example of how to do it.
namespace Proof_of_Concept_2
{
class Program
{
static void Main(string[] args)
{
if (args.Length!= 0)
{
if (args[0] == "1")
{
AlternatePathOfExecution();
}
//add other options here and below
}
else
{
NormalPathOfExectution();
}
}
private static void NormalPathOfExectution()
{
Console.WriteLine("Doing something here");
//need one of these for each additional console window
System.Diagnostics.Process.Start("Proof of Concept 2.exe", "1");
Console.ReadLine();
}
private static void AlternatePathOfExecution()
{
Console.WriteLine("Write something different on other Console");
Console.ReadLine();
}
}
}
Here is a screenshot of it working.
In conclusion,
Getting 2 console windows is easy, getting them to talk to each other is a separate question in and of itself. But I would suggest named pipes. Relevant Stackoverflow Post
You have to change your thinking because the 2 Consoles once run on different processes don't automatically talk to each other. Whatever calculation you are doing on one of them, the other one is completely unaware.
You can do
Process.Start("cmd.exe");
as many times as you would like. Is this what you mean?
Unfortunately not, sorry — you cannot have more than one console window per application in Windows.
Run the Console app (first window)
Got to bin > debug and open the YourApplication.exe file (second window)