Skip to content

Commit ace89cc

Browse files
committed
Ensure there is only one try instance
Hotkey binding anyways caused an exception previously
1 parent ac3fb88 commit ace89cc

1 file changed

Lines changed: 78 additions & 65 deletions

File tree

PasteIntoFile/Main.cs

Lines changed: 78 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Windows.Forms;
99
using System.Net.Http;
1010
using System.Net.Http.Headers;
11+
using System.Threading;
1112
using CommandLine;
1213
using CommandLine.Text;
1314
using Microsoft.Toolkit.Uwp.Notifications;
@@ -244,84 +245,96 @@ static int RunWizard(ArgsWizard args = null) {
244245
/// <param name="args">Command line arguments</param>
245246
/// <returns>Exit code</returns>
246247
static int RunTray(ArgsTray args = null) {
247-
Application.EnableVisualStyles();
248-
Application.SetCompatibleTextRenderingDefault(false);
249248

250-
// Register hotkeys
251-
KeyboardHook paste = new KeyboardHook();
252-
paste.KeyPressed += (s, e) => {
253-
var arg = new ArgsPaste();
254-
arg.Directory = ExplorerUtil.GetActiveExplorerPath();
255-
RunPaste(arg);
256-
};
257-
paste.RegisterHotKey(ModifierKeys.Win | ModifierKeys.Alt, Keys.V);
258-
paste.RegisterHotKey(ModifierKeys.Win | ModifierKeys.Alt | ModifierKeys.Shift, Keys.V);
259-
paste.RegisterHotKey(ModifierKeys.Win | ModifierKeys.Alt | ModifierKeys.Control, Keys.V);
260-
paste.RegisterHotKey(ModifierKeys.Win | ModifierKeys.Alt | ModifierKeys.Shift | ModifierKeys.Control, Keys.V);
261-
262-
KeyboardHook copy = new KeyboardHook();
263-
copy.KeyPressed += (s, e) => {
264-
var files = ExplorerUtil.GetActiveExplorerSelectedFiles();
265-
if (files.Count == 1) {
266-
var arg = new ArgsCopy();
267-
arg.FilePath = files.Item(0).Path;
268-
RunCopy(arg);
269-
} else {
270-
MessageBox.Show(Resources.str_copy_failed_not_single_file, Resources.app_title, MessageBoxButtons.OK, MessageBoxIcon.Error);
249+
var mutex = new Mutex(false, "PasteIntoFile-Tray:0fc405f4-6b23-4fd5-af4d-1291a2130531");
250+
try {
251+
if (!mutex.WaitOne(0, false)) {
252+
Console.WriteLine(@"Error: PasteIntoFile is already running in the try. Not starting another instance.");
253+
return 1;
271254
}
272-
};
273-
copy.RegisterHotKey(ModifierKeys.Win | ModifierKeys.Alt, Keys.C);
274-
275-
// Register clipboard observer for patching
276-
SharpClipboard clipMonitor = null;
277-
if (Settings.Default.trayPatchingEnabled) {
278-
bool skipFirst = true;
279-
void PatchClipboard(object s, SharpClipboard.ClipboardChangedEventArgs e) {
280-
if (skipFirst) { skipFirst = false; return; }
281-
Settings.Default.Reload(); // load modifications made from other instance
282-
if (!Settings.Default.trayPatchingEnabled) return; // allow to temporarily disable
283-
if (Settings.Default.continuousMode) return; // don't interfere with batch mode
284-
if (PatchedClipboardContents() is IDataObject data) {
285-
// TODO: This is experimental (might impact performance, might break proprietary formats used internally by other programs, not 100% stable)
286-
// Temporarily pausing monitoring seams unstable with the SharpClipboard library, so close and re-create the monitor instead
287-
288-
// Stop monitoring and leave clipboard chain cleanly
289-
clipMonitor.MonitorClipboard = false;
290-
clipMonitor.StopMonitoring();
291-
// Re-write clipboard contents
292-
Clipboard.SetDataObject(data, false);
293-
// Create a new monitor to handle future updates
294-
clipMonitor = new SharpClipboard();
295-
clipMonitor.ClipboardChanged += PatchClipboard;
255+
256+
257+
// Register hotkeys
258+
KeyboardHook paste = new KeyboardHook();
259+
paste.KeyPressed += (s, e) => {
260+
var arg = new ArgsPaste();
261+
arg.Directory = ExplorerUtil.GetActiveExplorerPath();
262+
RunPaste(arg);
263+
};
264+
paste.RegisterHotKey(ModifierKeys.Win | ModifierKeys.Alt, Keys.V);
265+
paste.RegisterHotKey(ModifierKeys.Win | ModifierKeys.Alt | ModifierKeys.Shift, Keys.V);
266+
paste.RegisterHotKey(ModifierKeys.Win | ModifierKeys.Alt | ModifierKeys.Control, Keys.V);
267+
paste.RegisterHotKey(ModifierKeys.Win | ModifierKeys.Alt | ModifierKeys.Shift | ModifierKeys.Control, Keys.V);
268+
269+
KeyboardHook copy = new KeyboardHook();
270+
copy.KeyPressed += (s, e) => {
271+
var files = ExplorerUtil.GetActiveExplorerSelectedFiles();
272+
if (files.Count == 1) {
273+
var arg = new ArgsCopy();
274+
arg.FilePath = files.Item(0).Path;
275+
RunCopy(arg);
276+
} else {
277+
MessageBox.Show(Resources.str_copy_failed_not_single_file, Resources.app_title, MessageBoxButtons.OK, MessageBoxIcon.Error);
278+
}
279+
};
280+
copy.RegisterHotKey(ModifierKeys.Win | ModifierKeys.Alt, Keys.C);
281+
282+
// Register clipboard observer for patching
283+
SharpClipboard clipMonitor = null;
284+
if (Settings.Default.trayPatchingEnabled) {
285+
bool skipFirst = true;
286+
void PatchClipboard(object s, SharpClipboard.ClipboardChangedEventArgs e) {
287+
if (skipFirst) { skipFirst = false; return; }
288+
Settings.Default.Reload(); // load modifications made from other instance
289+
if (!Settings.Default.trayPatchingEnabled) return; // allow to temporarily disable
290+
if (Settings.Default.continuousMode) return; // don't interfere with batch mode
291+
if (PatchedClipboardContents() is IDataObject data) {
292+
// TODO: This is experimental (might impact performance, might break proprietary formats used internally by other programs, not 100% stable)
293+
// Temporarily pausing monitoring seams unstable with the SharpClipboard library, so close and re-create the monitor instead
294+
295+
// Stop monitoring and leave clipboard chain cleanly
296+
clipMonitor.MonitorClipboard = false;
297+
clipMonitor.StopMonitoring();
298+
// Re-write clipboard contents
299+
Clipboard.SetDataObject(data, false);
300+
// Create a new monitor to handle future updates
301+
clipMonitor = new SharpClipboard();
302+
clipMonitor.ClipboardChanged += PatchClipboard;
303+
}
296304
}
305+
clipMonitor = new SharpClipboard();
306+
clipMonitor.ClipboardChanged += PatchClipboard;
297307
}
298-
clipMonitor = new SharpClipboard();
299-
clipMonitor.ClipboardChanged += PatchClipboard;
300-
}
301308

302-
// Tray icon
303-
NotifyIcon icon = new NotifyIcon();
304-
icon.Icon = Resources.app_icon;
305-
icon.Text = Resources.app_title;
306-
icon.ContextMenu = new ContextMenu(new[] {
309+
// Tray icon
310+
NotifyIcon icon = new NotifyIcon();
311+
icon.Icon = Resources.app_icon;
312+
icon.Text = Resources.app_title;
313+
icon.ContextMenu = new ContextMenu(new[] {
307314
new MenuItem(Resources.str_open_paste_into_file, (s, e) => new Dialog(showDialogOverwrite: true).Show()),
308315
new MenuItem(Resources.str_settings, (s, e) => new Wizard().Show()),
309316
new MenuItem(Resources.str_exit, (s, e) => { Application.Exit(); }),
310317
});
311-
icon.MouseClick += (sender, eventArgs) => {
312-
if (eventArgs.Button == MouseButtons.Left) new Dialog(showDialogOverwrite: true).Show();
313-
};
314-
icon.Visible = true;
318+
icon.MouseClick += (sender, eventArgs) => {
319+
if (eventArgs.Button == MouseButtons.Left) new Dialog(showDialogOverwrite: true).Show();
320+
};
321+
icon.Visible = true;
322+
323+
// Check for updates (async)
324+
var backgroundTask = CheckForUpdates();
325+
326+
Application.Run();
315327

316-
// Check for updates (async)
317-
var backgroundTask = CheckForUpdates();
328+
// leave the clipboard monitoring chain in a clean way, otherwise the chain will break when the program exits
329+
clipMonitor?.StopMonitoring();
318330

319-
Application.Run();
331+
icon.Visible = false;
320332

321-
// leave the clipboard monitoring chain in a clean way, otherwise the chain will break when the program exits
322-
clipMonitor?.StopMonitoring();
323333

324-
icon.Visible = false;
334+
} finally {
335+
mutex.Close();
336+
}
337+
325338
return 0;
326339
}
327340

0 commit comments

Comments
 (0)