Mutex Console Release - c#

This is a console application Wqhen i run the below program it shows a single console
and i have executed 3 other console from bin directory now my question is
When 1 console is has been has completed its task . Control is not going to other console
it is showing the same display Running(Console 1). How does Running show on other consoles.
class Program
{
static Mutex m = new Mutex(true, "demo");
public static void Main()
{
if (!m.WaitOne(1000))
{
Console.WriteLine("another");
Console.ReadLine();
}
else
{
try
{
run();
}
finally
{
m.ReleaseMutex();
}
}
}
public static void run()
{
Console.WriteLine("running");
Console.ReadLine();
Thread.Sleep(1000);
m.ReleaseMutex();
}
}

your program would be getting stuck due to readline where it holds for user input, try to use mutex like eg below
using (var mutex = new Mutex(false, "demo"))
{
mutex.WaitOne();
run();
mutex.ReleaseMutex();
}

Related

Mutex initialization inside a C# method always returns positive createdNew

I have created simple MutexManager:
public static class MutexManager
{
private static string mutexName
{
get
{
return "MyAppName" + System.Security.Principal.WindowsIdentity.GetCurrent().User.AccountDomainSid;
}
}
public static bool CreateApplicationMutex()
{
bool createdNew;
var mutex = new Mutex(false, mutexName, out createdNew);
return createdNew;
}
}
The problem is that CreateApplicationMutex always returns true on new application instance startup. As long as I had exactly same code in app.cs everything was correct, but after I moved it to MutexManager createdNew is always true. What am I doing wrong?
The following works as expected for me, and returns false on second instance
public static class MutexManager
{
private static string mutexName => "MyAppName" + System.Security.Principal.WindowsIdentity.GetCurrent()
.User?.AccountDomainSid;
public static bool CreateApplicationMutex()
{
new Mutex(false, mutexName, out var createdNew);
return createdNew;
}
}
private static void Main(string[] args)
{
Console.WriteLine(MutexManager.CreateApplicationMutex());
Console.ReadKey();
}
Output
true
false
Make sure you debug your app, and check the mutex name
Update
Winforms
MessageBox.Show(
MutexManager.CreateApplicationMutex()
.ToString());
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
WPF
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
MessageBox.Show(
MutexManager.CreateApplicationMutex()
.ToString());
base.OnStartup(e);
}
}
Once again it works as expected, and cant be reproduced
I had a similar problem, the reason was life time of mutex variable. Following code works fine by me in debug version, but always returns true for created_new in release version:
using System;
static class Program
{
[STAThread]
static void Main(string[] args)
{
string mutex_name = "MyApplicationName_SingleInstanceMutex";
bool created_new = false;
System.Threading.Mutex mutex = new System.Threading.Mutex(false, mutex_name, out created_new);
if (!created_new)
{
System.Windows.Forms.MessageBox.Show("Application is already started!");
return;
}
/* Create & run mainForm here */
}
}
Making mutex static solves the problem:
using System;
static class Program
{
static System.Threading.Mutex mutex = null;
[STAThread]
static void Main(string[] args)
{
string mutex_name = "MyApplicationName_SingleInstanceMutex";
bool created_new = false;
mutex = new System.Threading.Mutex(false, mutex_name, out created_new);
if (!created_new)
{
System.Windows.Forms.MessageBox.Show("Application is already started!");
return;
}
/* Create & run mainForm here */
}
}

.Net Core - How to detect if a application is running? [duplicate]

In order to allow only a single instance of an application running I'm using mutex. The code is given below. Is this the right way to do it? Are there any flaws in the code?
How to show the already running application when user tries to open the application the second time. At present (in the code below), I'm just displaying a message that another instance is already running.
static void Main(string[] args)
{
Mutex _mut = null;
try
{
_mut = Mutex.OpenExisting(AppDomain.CurrentDomain.FriendlyName);
}
catch
{
//handler to be written
}
if (_mut == null)
{
_mut = new Mutex(false, AppDomain.CurrentDomain.FriendlyName);
}
else
{
_mut.Close();
MessageBox.Show("Instance already running");
}
}
I did it this way once, I hope it helps:
bool createdNew;
Mutex m = new Mutex(true, "myApp", out createdNew);
if (!createdNew)
{
// myApp is already running...
MessageBox.Show("myApp is already running!", "Multiple Instances");
return;
}
static void Main()
{
using(Mutex mutex = new Mutex(false, #"Global\" + appGuid))
{
if(!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance already running");
return;
}
GC.Collect();
Application.Run(new Form1());
}
}
Source : http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx
I use this:
private static Mutex _mutex;
private static bool IsSingleInstance()
{
_mutex = new Mutex(false, _mutexName);
// keep the mutex reference alive until the normal
//termination of the program
GC.KeepAlive(_mutex);
try
{
return _mutex.WaitOne(0, false);
}
catch (AbandonedMutexException)
{
// if one thread acquires a Mutex object
//that another thread has abandoned
//by exiting without releasing it
_mutex.ReleaseMutex();
return _mutex.WaitOne(0, false);
}
}
public Form1()
{
if (!isSingleInstance())
{
MessageBox.Show("Instance already running");
this.Close();
return;
}
//program body here
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (_mutex != null)
{
_mutex.ReleaseMutex();
}
}
Have a look at this question
There is a link to this article: the misunderstood mutex where the usage of a mutex is explained.
Check out the code sample shown on this page
In short, you use the overload Mutex ctor(bool, string, out bool) which tells you via an out parameter, whether you got ownership of the Named Mutex. If you're the first instance, this out param would contain true after the ctor is called - in which case you proceed as usual. If this param is false, it means another instance has already got ownership/is running, in which case you show an error message "Another instance is already running." and then exit gracefully.
Use app with timeout and security settings. I used my custom class:
private class SingleAppMutexControl : IDisposable
{
private readonly Mutex _mutex;
private readonly bool _hasHandle;
public SingleAppMutexControl(string appGuid, int waitmillisecondsTimeout = 5000)
{
bool createdNew;
var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
MutexRights.FullControl, AccessControlType.Allow);
var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(allowEveryoneRule);
_mutex = new Mutex(false, "Global\\" + appGuid, out createdNew, securitySettings);
_hasHandle = false;
try
{
_hasHandle = _mutex.WaitOne(waitmillisecondsTimeout, false);
if (_hasHandle == false)
throw new System.TimeoutException();
}
catch (AbandonedMutexException)
{
_hasHandle = true;
}
}
public void Dispose()
{
if (_mutex != null)
{
if (_hasHandle)
_mutex.ReleaseMutex();
_mutex.Dispose();
}
}
}
and use it:
private static void Main(string[] args)
{
try
{
const string appguid = "{xxxxxxxx-xxxxxxxx}";
using (new SingleAppMutexControl(appguid))
{
Console.ReadLine();
}
}
catch (System.TimeoutException)
{
Log.Warn("Application already runned");
}
catch (Exception ex)
{
Log.Fatal(ex, "Fatal Error on running");
}
}
Also this. Is using a Mutex to prevent multiple instances of the same program from running safe?

Run a windows form while my console application still running

I'm new at C# programming and i'm lost with a thing that could be simple.
Executing a console application, at a moment i need to call a Windows Form that will show statics of the execution but when i call the form1.ShowDialog(); this stop the console runtime.
How do i keep my console execution alive while i show a Windows form screen ?
class Program
{
static Form1 form = new Form1();
public static bool run = true;
static void Main(string[] args)
{
work();
}
public static void work()
{
form.Show();
while (run)
{
Console.WriteLine("Console still running");
}
}
}
try this it work on me
using System.Windows.Forms;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
public static bool run = true;
static void Main(string[] args)
{
Startthread();
Application.Run(new Form1());
Console.ReadLine();
}
private static void Startthread()
{
var thread = new Thread(() =>
{
while (run)
{
Console.WriteLine("console is running...");
Thread.Sleep(1000);
}
});
thread.Start();
}
}
}
Threading is like "process inside a process" in my own understanding.
See this question. You have to use Form1.Show() because Form1.ShowDialog() pauses execution until the form is closed.
Update This seems to be working (with Application.Run):-
public static Form1 form = new Form1();
public static bool run = true;
[MTAThread]
static void Main(string[] args)
{
new Thread(() => Application.Run(form)).Start();
new Thread(work).Start();
}
public static void work()
{
while (run)
{
Console.WriteLine("Console Running");
}
}

Starting a GameWindow in a thread

I'm trying to write an OpenTK application where you can type commands in a console window, and have a GameWindow display the result of commands.
My code looks like this:
public Program : GameWindow
{
static void Main(string[] args)
{
var display = new Program();
var task = new Task(() => display.Run());
task.Start();
while (true)
{
Console.Write("> ");
var response = Console.ReadLine();
//communicate with the display object asynchronously
}
}
}
However, the display window does not appear when started in a task or thread.
Why is this the case? I need the Run method to happen in a thread, because it is blocking for the life of the window.
To fix your particular problem, just create instance of your window ("display" in your case) on thread itself:
public class Program : GameWindow {
private static void Main(string[] args) {
Program display = null;
var task = new Thread(() => {
display = new Program();
display.Run();
});
task.Start();
while (display == null)
Thread.Yield(); // wait a bit for another thread to init variable if necessary
while (true)
{
Console.Write("> ");
var response = Console.ReadLine();
//communicate with the display object asynchronously
display.Title = response;
}
}
}

How i can get Process.waitForFinish()

I'm trying to get the pid of a process when the process end working but not yet killing.
process.WaitForExit();
the method above stop until the process is killed, but i'm looking for something like process.waitForFinish because i'm trying to handle the process when it finishing working but not yet killed.
Like adding a signal and get in the other process. exemple:
//Process to catch
main(){
//Do some Code
End of the function
SendEndSignal(); & Stop();
}
Second process will catch first process like that
main(){
int pid = Process.start("Process1.exe");
process.waitUntilReceiveSignal();
//Do code here
process.kill();
}
I need something like process.WaitForInputIdle(); but the problem here is it working only if the process contain graphical interface. So what about if the process wait for input from user by console like using Console.readLine().
This mean that i need to know when the process go to inactive state but not killed.
EventWaitHandle is a way to go in your case.
namespace A
{
class Program
{
static void Main(string[] args)
{
var evh = new EventWaitHandle(false, EventResetMode.AutoReset,"fromA");
Console.WriteLine("Anykey to send signal");
Console.ReadKey();
evh.Set();
}
}
}
namespace B
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Waiting for a signal");
var evh = EventWaitHandle.OpenExisting("fromA");
evh.WaitOne();
Console.WriteLine("Signal!");
Console.ReadKey();
}
}
}
But keep in mind you will need to wait for child process to register its EventWaitHandle. So you either do wait for some time (ugly). Or create another EventWaitHandle in parent process, so child process notifies when its handler is registered
Edit: Complete solution
namespace Parent
{
class Program
{
static void Main(string[] args)
{
using (var childReadyEh =new EventWaitHandle(false, EventResetMode.AutoReset,"childIsReady"))
{
Process.Start("child.exe");
childReadyEh.WaitOne();
}
using (var childSignalEh =EventWaitHandle.OpenExisting("childSignal"))
{
childSignalEh.WaitOne();
}
Console.WriteLine("Signal is recieved");
Console.ReadKey();
}
}
}
namespace Child
{
class Program
{
static void Main(string[] args)
{
EventWaitHandle childSignalEh =null;
using (var childReadyEh =EventWaitHandle.OpenExisting("childIsReady"))
{
childSignalEh =new EventWaitHandle(false, EventResetMode.AutoReset,"childSignal");
childReadyEh.Set();
}
Console.WriteLine("Anykey to send a signal to parent");
Console.ReadKey();
childSignalEh.Set();
childSignalEh.Dispose();
Console.WriteLine("Signal is sent");
Console.ReadKey();
}
}
}

Categories