|
8 | 8 | using System.Windows.Forms; |
9 | 9 | using System.Net.Http; |
10 | 10 | using System.Net.Http.Headers; |
| 11 | +using System.Threading; |
11 | 12 | using CommandLine; |
12 | 13 | using CommandLine.Text; |
13 | 14 | using Microsoft.Toolkit.Uwp.Notifications; |
@@ -244,84 +245,96 @@ static int RunWizard(ArgsWizard args = null) { |
244 | 245 | /// <param name="args">Command line arguments</param> |
245 | 246 | /// <returns>Exit code</returns> |
246 | 247 | static int RunTray(ArgsTray args = null) { |
247 | | - Application.EnableVisualStyles(); |
248 | | - Application.SetCompatibleTextRenderingDefault(false); |
249 | 248 |
|
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; |
271 | 254 | } |
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 | + } |
296 | 304 | } |
| 305 | + clipMonitor = new SharpClipboard(); |
| 306 | + clipMonitor.ClipboardChanged += PatchClipboard; |
297 | 307 | } |
298 | | - clipMonitor = new SharpClipboard(); |
299 | | - clipMonitor.ClipboardChanged += PatchClipboard; |
300 | | - } |
301 | 308 |
|
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[] { |
307 | 314 | new MenuItem(Resources.str_open_paste_into_file, (s, e) => new Dialog(showDialogOverwrite: true).Show()), |
308 | 315 | new MenuItem(Resources.str_settings, (s, e) => new Wizard().Show()), |
309 | 316 | new MenuItem(Resources.str_exit, (s, e) => { Application.Exit(); }), |
310 | 317 | }); |
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(); |
315 | 327 |
|
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(); |
318 | 330 |
|
319 | | - Application.Run(); |
| 331 | + icon.Visible = false; |
320 | 332 |
|
321 | | - // leave the clipboard monitoring chain in a clean way, otherwise the chain will break when the program exits |
322 | | - clipMonitor?.StopMonitoring(); |
323 | 333 |
|
324 | | - icon.Visible = false; |
| 334 | + } finally { |
| 335 | + mutex.Close(); |
| 336 | + } |
| 337 | + |
325 | 338 | return 0; |
326 | 339 | } |
327 | 340 |
|
|
0 commit comments