Here is my code
I tried in Debug Mode. It works.
While in release does not why? Its a WPF application
This piece of code i put in Main Method for checking if a application is running or not. I want single instance to be running only. I copied this code from Stack Overflow only.
[STAThread]
static void Main()
{
const string MutexName = "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}";
try
{
Mutex mutex = new Mutex(true, MutexName);
if (mutex.WaitOne(TimeSpan.Zero, true))
{
mutex.ReleaseMutex();
//Here Application logic
}
else
{
MessageBox.Show("Application is alreadey running.");
Environment.Exit(1);
}
}
catch
{
Environment.Exit(1);
}
}
I don't know the exact reason. But this modification works
[STAThread]
static void Main()
{
const string MutexName = "8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F";
try
{
Mutex mutex;
if (!Mutex.TryOpenExisting(MutexName, out mutex))
{
mutex = new Mutex(true,MutexName);
var app = new App();
app.Run();
}
else
{
Environment.Exit(1);
}
}
catch
{
Environment.Exit(1);
}
}
Related
I'm trying to control access via a multi-process console application, so that only one process can run a specific part of the code at a time.
Actually, I would have liked to use a mutex for this, but the Mutex class doesn't seem to work on Linux.
My code:
using var mutex = new Mutex(false, #"Global\TestMutex");
if (mutex.WaitOne(0, false)) {
Console.WriteLine("Mutex erhalten");
} else {
Console.WriteLine("Mutex nicht erhalten");
}
Console.WriteLine("Beliebige Taste drücken zum beenden.");
Console.ReadKey();
Working on Windows:
Not working on Linux (Ubuntu 22.04/NET6):
Am I missing something?
My current workaround ist to have a "Lockfile" but I didn't want to maintain an additional utility class.
utility class:
public class LockfileMutex : IDisposable {
private readonly string _fileName;
private FileStream? _stream;
public LockfileMutex(string name) {
var assemblyDir = Path.GetDirectoryName(typeof(LockfileMutex).Assembly.Location) ?? throw new FileNotFoundException("cannot determine assembly location");
var file = Path.GetFullPath(Path.Combine(assemblyDir, name));
_fileName = file;
}
public bool Acquire() {
try {
_stream = new FileStream(_fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
return true;
} catch (IOException ex) when (ex.Message.Contains(_fileName)) {
return false;
}
}
public void Dispose() {
if (_stream != null) {
_stream.Dispose();
try {
File.Delete(_fileName);
} catch {
// ignored
}
}
GC.SuppressFinalize(this);
}
}
usage:
using (var mutex = new LockfileMutex("MyMutex")) {
if (mutex.Acquire()) {
Console.WriteLine("acquired");
} else {
Console.WriteLine("not acquired");
}
Console.WriteLine("press any key to end");
Console.ReadKey();
}
I'm trying to use a WPF window as a message popup that will close once a task has been performed. All the documentation I've seen says that this can't be done with a messageBox, that's why I'm going with the WPF. I found one code snip that allowed me to open the WPF window but it wouldn't progress the application to the next process. Below is the last code example I found that I thought showed promise but the window isn't opening -
[STAThread]
static void Main(string[] args)
{
try
{
string filePath = "my new directory";
var popup = new PopupTest();
popup.Dispatcher.BeginInvoke
(System.Windows.Threading.DispatcherPriority.Normal,
(Action)(() =>
{
popup.Show();
}));
// Do some console application stuff
do
{
Directory.CreateDirectory(filePath);
} while (!Directory.Exists(filePath));
popup.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}
}
The cs.xaml file is just the default
/// Interaction logic for PopupTest.xaml
/// </summary>
public partial class PopupTest : Window
{
public PopupTest()
{
InitializeComponent();
}
}
I feel like this should be simpler than I'm making it. Anything that can point me in the right direction is appreciated.
You need to reference the WPF assemblies and create and run a System.Windows.Application on the STA thread:
[STAThread]
static void Main(string[] args)
{
var app = new System.Windows.Application();
app.Run(new PopupTest());
}
The Run method blocks and doesn't return until the app is shut down.
If you want to do some stuff while the app is running, you need to do this on another thread:
[STAThread]
static async Task Main(string[] args)
{
Task t = Task.Run(() =>
{
string filePath = "my new directory";
do
{
Directory.CreateDirectory(filePath);
} while (!Directory.Exists(filePath));
});
var app = new System.Windows.Application();
app.Run(new MainWindow());
await t;
}
Consider the following snippet. The thread spawned by the main windows service thread will crash because it tries to open a null path. Then the crashing of the windows service will follow.
namespace ThreadCrashService {
class Program {
public const string ServiceName = "ThreadCrashServiceTest";
private static Timer _timer = null;
private static int _timerInterval = 60000;
static void Main(string[] args) {
if (!Environment.UserInteractive) {
// running as service
using (var service = new Service1()) System.ServiceProcess.ServiceBase.Run(service);
} else {
string parameter = string.Concat(args);
switch (parameter) {
case "--install":
if (IsServiceInstalled()) {
UninstallService();
}
InstallService();
break;
case "--uninstall":
if (IsServiceInstalled()) {
UninstallService();
}
break;
default:
Program program = new Program();
program.Start();
return;
}
}
}
private static void InstallService() {
ManagedInstallerClass.InstallHelper(new[] { Assembly.GetExecutingAssembly().Location });
}
private static bool IsServiceInstalled() {
return System.ServiceProcess.ServiceController.GetServices().Any(s => s.ServiceName == ServiceName);
}
private static void UninstallService() {
ManagedInstallerClass.InstallHelper(new[] { "/u", Assembly.GetExecutingAssembly().Location });
}
public void Start() {
try {
Thread thread = new Thread(() => ThreadMethodThatWillCrash());
thread.Start();
} catch {
// do nothing
}
}
public void ThreadMethodThatWillCrash() {
// ArgumentNullException
File.Open(null, FileMode.Open);
}
}
}
I know in windows form application, we can use
System.Windows.Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
and
System.Windows.Forms.Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
to catch the global exceptions not handled by UI threads. But for a console application, we can only use
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
to log the exception. But this is not able to prevent the thread crashing the windows service. What else can I do to prevent the thread crashing the windows service? I can't change the way how the thread is created because it's a in a third-party library.
You can use the main thread to spool up Tasks from TPL in order to preserve the state of the process.
https://stackoverflow.com/a/27384788/376550
https://msdn.microsoft.com/en-us/library/dd537609(v=vs.110).aspx
This question already has answers here:
Checking if my Windows application is running
(9 answers)
Closed 8 years ago.
I tried to do it this way:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;
using DannyGeneral;
namespace mws
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
if (IsApplicationAlreadyRunning() == true)
{
MessageBox.Show("The application is already running");
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
catch (Exception err)
{
Logger.Write("error " + err.ToString());
}
}
static bool IsApplicationAlreadyRunning()
{
string proc = Process.GetCurrentProcess().ProcessName;
Process[] processes = Process.GetProcessesByName(proc);
if (processes.Length > 1)
{
return true;
}
else
{
return false;
}
}
}
}
But I'm getting some problems.
First, when I'm loading my project in Visual Studio and then running my program it's detecting the vshost.exe file of my project for example: My project.vshost
And I want that it will detect if my program is running only when I'm running the program only if it find the .exe for example: My project.exe not the vshost.
Have a look at using a mutex.
static class Program {
static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
[STAThread]
static void Main() {
if(mutex.WaitOne(TimeSpan.Zero, true)) {
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
finally
{
mutex.ReleaseMutex();
}
} else {
MessageBox.Show("only one instance at a time");
}
}
}
If our app is running, WaitOne will return false, and you'll get a message box.
As #Damien_The_Unbeliever pointed out correctly, you should change the Guid of the mutex for each application you write!
Source: http://sanity-free.org/143/csharp_dotnet_single_instance_application.html
Could you please try below snippet?
private static void Main(string[] args)
{
if (IsApplicationAlreadyRunning())
{
Console.Write("The application is already running");
}
else
{
Console.Write("The application is not running");
}
Console.Read();
}
static bool IsApplicationAlreadyRunning()
{
return Process.GetProcesses().Count(p => p.ProcessName.Contains(Assembly.GetExecutingAssembly().FullName.Split(',')[0]) && !p.Modules[0].FileName.Contains("vshost")) > 1;
}
I have a unmanaged application which opens at runtime my managed application.
- Each time the unmanaged aplication is being executed , it opens a new instance of my application .
I have to somehow do this scenario:
-When the unmanaged application is being executed for the first time, my managed aplication should run fine,but if the user tries to open again the unmanaged application , those managed instances should be in "standby" mode and if the first managed application which is currently running is closed , one of the standby instances should be "resumed" .
As I've seen so far , I should be using mutex :
public Form1()
{
InitializeComponent();
if (!IsSingleInstance())
{
this.Close();
return;
}
}
private static Mutex _mutex;
private static bool IsSingleInstance()
{
_mutex = new Mutex(false, "MyApp");
GC.KeepAlive(_mutex);
try
{
return _mutex.WaitOne(0, false);
}
catch (AbandonedMutexException)
{
_mutex.ReleaseMutex();
return _mutex.WaitOne(0, false);
}
}
protected override void OnClosing(CancelEventArgs e)
{
if (_mutex != null)
{
_mutex.ReleaseMutex();
}
}
But ofcourse , the code only checks if another istance is running and if it does..then it will close it.
What can I do?
Thanks,
I'd rather put the lock in Main in Program.cs.
static void Main()
{
Mutex mutex = new Mutex(false, "MyApp");
if (mutex.WaitOne())
{
try
{
Application.Run(new Form1());
}
finally
{
mutex.ReleaseMutex();
}
}
}