Skip to content
This repository was archived by the owner on May 24, 2025. It is now read-only.

Commit 610480f

Browse files
committed
Only allow a single instance to run
crtcpl and ejectcd now use a mutex to allow only a single instance to run at once. for crtcpl this is required since it grabs the serial port for exclusive use and multiple instances of ejectcd make no sense...
1 parent 13eaad7 commit 610480f

8 files changed

Lines changed: 181 additions & 66 deletions

File tree

crtcpl/NativeMethods.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ internal static class NativeMethods
88
{
99
[DllImport("user32.dll")]
1010
internal static extern IntPtr SetActiveWindow(IntPtr hWnd);
11+
12+
13+
[DllImport("user32.dll")]
14+
internal static extern IntPtr SetForegroundWindow(IntPtr hWnd);
15+
16+
[DllImport("user32.dll")]
17+
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
1118
}
1219
#endif
1320
}

crtcpl/Program.cs

Lines changed: 73 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
using System;
2+
using System.Diagnostics;
3+
using System.IO;
4+
using System.Threading;
25
using System.Windows.Forms;
36

47
namespace crtcpl
@@ -10,48 +13,92 @@ public static class Program
1013
[STAThread]
1114
public static void Main()
1215
{
16+
Application.EnableVisualStyles();
17+
Application.SetCompatibleTextRenderingDefault(false);
18+
19+
bool result;
20+
Mutex m = new Mutex(true, "crtcpl", out result);
21+
22+
if (!result)
23+
{
24+
try
25+
{
26+
#if !MONO
27+
// Best effort switch to active instance
28+
Process[] procs = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Application.ExecutablePath));
29+
foreach (Process p in procs)
30+
{
31+
if (p.Id == Process.GetCurrentProcess().Id)
32+
continue;
33+
34+
if (p.MainWindowHandle == IntPtr.Zero)
35+
continue;
36+
37+
const int SW_SHOW = 5;
38+
39+
NativeMethods.SetForegroundWindow(p.MainWindowHandle);
40+
NativeMethods.ShowWindow(p.MainWindowHandle, SW_SHOW);
41+
42+
break;
43+
}
44+
#else
45+
// Sorry, don't know what to do.
46+
MessageBox.Show(StringRes.StringRes.AlreadyRunning, StringRes.StringRes.AlreadyRunningTitle,
47+
MessageBoxButtons.OK, MessageBoxIcon.Error);
48+
#endif
49+
}
50+
catch (Exception)
51+
{
1352
#if DEBUG
14-
System.Threading.Thread.CurrentThread.CurrentCulture =
15-
System.Threading.Thread.CurrentThread.CurrentUICulture =
16-
new System.Globalization.CultureInfo("de-de");
53+
throw;
1754
#endif
18-
if (Settings.Default.NeedsUpgrade)
19-
{
20-
Settings.Default.Upgrade();
21-
Settings.Default.NeedsUpgrade = false;
22-
Settings.Default.Save();
55+
}
56+
57+
return;
2358
}
2459

25-
if (!string.IsNullOrWhiteSpace(Settings.Default.SerialPort))
60+
try
2661
{
27-
bool bad = false;
28-
try
62+
if (Settings.Default.NeedsUpgrade)
2963
{
30-
UCCom.Open(Settings.Default.SerialPort);
31-
byte[] ret = UCCom.SendCommand(1, 0, 0);
64+
Settings.Default.Upgrade();
65+
Settings.Default.NeedsUpgrade = false;
66+
Settings.Default.Save();
67+
}
3268

33-
if (ret == null || ret.Length != 1 || ret[0] != SUPPORTED_EEPROM_VERSION)
69+
if (!string.IsNullOrWhiteSpace(Settings.Default.SerialPort))
70+
{
71+
bool bad = false;
72+
try
73+
{
74+
UCCom.Open(Settings.Default.SerialPort);
75+
byte[] ret = UCCom.SendCommand(1, 0, 0);
76+
77+
if (ret == null || ret.Length != 1 || ret[0] != SUPPORTED_EEPROM_VERSION)
78+
{
79+
bad = true;
80+
}
81+
}
82+
catch (UCComException)
3483
{
3584
bad = true;
3685
}
37-
}
38-
catch (UCComException)
39-
{
40-
bad = true;
86+
87+
if (bad)
88+
{
89+
Settings.Default.SerialPort = null;
90+
}
4191
}
4292

43-
if (bad)
93+
using (AppletForm a = new AppletForm())
4494
{
45-
Settings.Default.SerialPort = null;
95+
Application.Run(a);
4696
}
4797
}
48-
49-
Application.EnableVisualStyles();
50-
Application.SetCompatibleTextRenderingDefault(false);
51-
52-
using (AppletForm a = new AppletForm())
98+
finally
5399
{
54-
Application.Run(a);
100+
m.ReleaseMutex();
101+
m.Dispose();
55102
}
56103
}
57104
}

crtcpl/StringRes/StringRes.Designer.cs

Lines changed: 21 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crtcpl/StringRes/StringRes.de.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@
117117
<resheader name="writer">
118118
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119119
</resheader>
120+
<data name="AlreadyRunning" xml:space="preserve">
121+
<value>Es wird bereits eine weitere Instanz dieses Programms ausgeführt.</value>
122+
</data>
123+
<data name="AlreadyRunningTitle" xml:space="preserve">
124+
<value>Bildschirmeinstellungen</value>
125+
</data>
120126
<data name="CantApplyChanges" xml:space="preserve">
121127
<value>Bei der Anweisung an den IVAD-Controller, alle Änderungen dauerhaft zu machen, ist ein Fehler aufgetreten. {0}</value>
122128
</data>

crtcpl/StringRes/StringRes.fr.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@
117117
<resheader name="writer">
118118
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119119
</resheader>
120+
<data name="AlreadyRunning" xml:space="preserve">
121+
<value>Une autre instance de ce programme est déjà en cours d'exécution</value>
122+
</data>
123+
<data name="AlreadyRunningTitle" xml:space="preserve">
124+
<value>Paramètres de l’écran</value>
125+
</data>
120126
<data name="CantApplyChanges" xml:space="preserve">
121127
<value>Une erreur s'est produite alors que le contrôleur IVAD avait reçu l'instruction de rendre permanentes toutes les modifications. {0}</value>
122128
</data>

crtcpl/StringRes/StringRes.ja.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,10 @@
156156
<data name="UCComUnauthorizedAccess" xml:space="preserve">
157157
<value>COMポートへのアクセスが拒否されました。 別のプログラムが指定されたCOMポートを既に開いている可能性があります。</value>
158158
</data>
159+
<data name="AlreadyRunning" xml:space="preserve">
160+
<value>このプログラムの他のインスタンスが既に実行されています。</value>
161+
</data>
162+
<data name="AlreadyRunningTitle" xml:space="preserve">
163+
<value>画面設定</value>
164+
</data>
159165
</root>

crtcpl/StringRes/StringRes.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@
117117
<resheader name="writer">
118118
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119119
</resheader>
120+
<data name="AlreadyRunning" xml:space="preserve">
121+
<value>Another Instance of this program is already running</value>
122+
</data>
123+
<data name="AlreadyRunningTitle" xml:space="preserve">
124+
<value>Screen Settings</value>
125+
</data>
120126
<data name="CantApplyChanges" xml:space="preserve">
121127
<value>An error occurred while instructing the IVAD controller to make all changes permanent. {0}</value>
122128
</data>

ejectcd/Program.cs

Lines changed: 56 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,68 +2,87 @@
22
using System.ComponentModel;
33
using System.IO;
44
using System.Runtime.InteropServices;
5+
using System.Threading;
56

67
namespace ejectcd
78
{
89
public static class Program
910
{
1011
public static int Main(string[] args)
1112
{
12-
DriveInfo[] drives;
13+
bool result;
14+
Mutex m = new Mutex(true, "ejectcd", out result);
1315

14-
try
15-
{
16-
drives = DriveInfo.GetDrives();
17-
}
18-
catch (IOException e)
16+
if (!result)
1917
{
20-
Console.Error.WriteLine(e.Message);
21-
return 1;
22-
}
23-
catch (UnauthorizedAccessException e)
24-
{
25-
Console.Error.WriteLine(e.Message);
18+
Console.Error.Write("Another instance is already running.");
2619
return 1;
2720
}
2821

29-
foreach (DriveInfo drive in drives)
22+
try
3023
{
31-
if (drive.DriveType != DriveType.CDRom)
32-
continue;
33-
34-
Console.WriteLine("Eject CD-ROM drive {0}.", drive.Name);
35-
36-
IntPtr hDrive = new IntPtr(INVALID_HANDLE_VALUE);
24+
DriveInfo[] drives;
3725

3826
try
3927
{
40-
// Open the device
41-
hDrive = CreateFile(@"\\.\" + drive.Name[0] + ':', FileAccess.Read, FileShare.ReadWrite | FileShare.Delete,
42-
IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
43-
44-
if ((int)hDrive == INVALID_HANDLE_VALUE) { throw new Win32Exception(); }
45-
46-
// Try and eject
47-
int dummy = 0;
48-
bool ejected = DeviceIoControl(hDrive, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0,
49-
IntPtr.Zero, 0, ref dummy, IntPtr.Zero);
50-
51-
if (!ejected) { throw new Win32Exception(); }
52-
28+
drives = DriveInfo.GetDrives();
29+
}
30+
catch (IOException e)
31+
{
32+
Console.Error.WriteLine(e.Message);
33+
return 1;
5334
}
54-
catch (Win32Exception e)
35+
catch (UnauthorizedAccessException e)
5536
{
5637
Console.Error.WriteLine(e.Message);
5738
return 1;
5839
}
59-
finally
40+
41+
foreach (DriveInfo drive in drives)
6042
{
61-
if (hDrive.ToInt32() != INVALID_HANDLE_VALUE)
62-
CloseHandle(hDrive);
43+
if (drive.DriveType != DriveType.CDRom)
44+
continue;
45+
46+
Console.WriteLine("Eject CD-ROM drive {0}.", drive.Name);
47+
48+
IntPtr hDrive = new IntPtr(INVALID_HANDLE_VALUE);
49+
50+
try
51+
{
52+
// Open the device
53+
hDrive = CreateFile(@"\\.\" + drive.Name[0] + ':', FileAccess.Read, FileShare.ReadWrite | FileShare.Delete,
54+
IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
55+
56+
if ((int)hDrive == INVALID_HANDLE_VALUE) { throw new Win32Exception(); }
57+
58+
// Try and eject
59+
int dummy = 0;
60+
bool ejected = DeviceIoControl(hDrive, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0,
61+
IntPtr.Zero, 0, ref dummy, IntPtr.Zero);
62+
63+
if (!ejected) { throw new Win32Exception(); }
64+
65+
}
66+
catch (Win32Exception e)
67+
{
68+
Console.Error.WriteLine(e.Message);
69+
return 1;
70+
}
71+
finally
72+
{
73+
if (hDrive.ToInt32() != INVALID_HANDLE_VALUE)
74+
CloseHandle(hDrive);
75+
}
6376
}
77+
78+
Console.WriteLine("Done.");
79+
}
80+
finally
81+
{
82+
m.ReleaseMutex();
83+
m.Dispose();
6484
}
6585

66-
Console.WriteLine("Done.");
6786
return 0;
6887
}
6988

0 commit comments

Comments
 (0)