public MainForm(CopyDataTransport dataTransport) { instance = this; // Make sure we never capture the mainform WindowDetails.RegisterIgnoreHandle(this.Handle); // // The InitializeComponent() call is required for Windows Forms designer support. // InitializeComponent(); this.Icon = GreenshotPlugin.Core.GreenshotResources.getGreenshotIcon(); IniConfig.IniChanged += new FileSystemEventHandler(ReloadConfiguration); tooltip = new ToolTip(); UpdateUI(); // Do loading on a different Thread to shorten the startup Thread pluginInitThread = new Thread(delegate() { // Load all the plugins PluginHelper.instance.LoadPlugins(this); // Check destinations, remove all that don't exist foreach (string destination in conf.OutputDestinations.ToArray()) { if (DestinationHelper.GetDestination(destination) == null) { conf.OutputDestinations.Remove(destination); } } // we should have at least one! if (conf.OutputDestinations.Count == 0) { conf.OutputDestinations.Add(Destinations.EditorDestination.DESIGNATION); } BeginInvoke((MethodInvoker)delegate { // Do after all plugins & finding the destination, otherwise they are missing! InitializeQuickSettingsMenu(); }); }); pluginInitThread.Name = "Initialize plug-ins"; pluginInitThread.IsBackground = true; pluginInitThread.Start(); SoundHelper.Initialize(); // Create a new instance of the class: copyData = new CopyData(); copyData = new CopyData(); // Assign the handle: copyData.AssignHandle(this.Handle); // Create the channel to send on: copyData.Channels.Add("Greenshot"); // Hook up received event: copyData.CopyDataReceived += new CopyDataReceivedEventHandler(CopyDataDataReceived); if (dataTransport != null) { HandleDataTransport(dataTransport); } }
private void HandleDataTransport(CopyDataTransport dataTransport) { foreach (KeyValuePair<CommandEnum, string> command in dataTransport.Commands) { LOG.Debug("Data received, Command = " + command.Key + ", Data: " + command.Value); switch (command.Key) { case CommandEnum.Exit: LOG.Info("Exit requested"); Exit(); break; case CommandEnum.FirstLaunch: LOG.Info("FirstLaunch: Created new configuration, showing balloon."); break; case CommandEnum.ReloadConfig: LOG.Info("Reload requested"); try { IniConfig.Reload(); ReloadConfiguration(null, null); } catch { } break; case CommandEnum.OpenFile: string filename = command.Value; LOG.InfoFormat("Open file requested: {0}", filename); if (File.Exists(filename)) { BeginInvoke((MethodInvoker)delegate { CaptureHelper.CaptureFile(filename); }); } else { LOG.Warn("No such file: " + filename); } break; default: LOG.Error("Unknown command!"); break; } } }
public static void Start(string[] args) { bool isAlreadyRunning = false; List<string> filesToOpen = new List<string>(); // Init Log4NET LogFileLocation = LogHelper.InitializeLog4NET(); // Get logger LOG = log4net.LogManager.GetLogger(typeof(MainForm)); Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); // Log the startup LOG.Info("Starting: " + EnvironmentInfo.EnvironmentToString(false)); IniConfig.Init(); AppConfig.UpgradeToIni(); // Read configuration conf = IniConfig.GetIniSection<CoreConfiguration>(); try { // Fix for Bug 2495900, Multi-user Environment // check whether there's an local instance running already try { // Added Mutex Security, hopefully this prevents the UnauthorizedAccessException more gracefully // See an example in Bug #3131534 SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); MutexSecurity mutexsecurity = new MutexSecurity(); mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.FullControl, AccessControlType.Allow)); mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.ChangePermissions, AccessControlType.Deny)); mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.Delete, AccessControlType.Deny)); bool created = false; // 1) Create Mutex applicationMutex = new Mutex(false, @"Local\F48E86D3-E34C-4DB7-8F8F-9A0EA55F0D08", out created, mutexsecurity); // 2) Get the right to it, this returns false if it's already locked if (!applicationMutex.WaitOne(0, false)) { LOG.Debug("Greenshot seems already to be running!"); isAlreadyRunning = true; // Clean up applicationMutex.Close(); applicationMutex = null; } } catch (AbandonedMutexException e) { // Another Greenshot instance didn't cleanup correctly! // we can ignore the exception, it happend on the "waitone" but still the mutex belongs to us LOG.Warn("Greenshot didn't cleanup correctly!", e); } catch (UnauthorizedAccessException e) { LOG.Warn("Greenshot is most likely already running for a different user in the same session, can't create mutex due to error: ", e); isAlreadyRunning = true; } catch (Exception e) { LOG.Warn("Problem obtaining the Mutex, assuming it was already taken!", e); isAlreadyRunning = true; } if (args.Length > 0 && LOG.IsDebugEnabled) { StringBuilder argumentString = new StringBuilder(); for (int argumentNr = 0; argumentNr < args.Length; argumentNr++) { argumentString.Append("[").Append(args[argumentNr]).Append("] "); } LOG.Debug("Greenshot arguments: " + argumentString.ToString()); } for (int argumentNr = 0; argumentNr < args.Length; argumentNr++) { string argument = args[argumentNr]; // Help if (argument.ToLower().Equals("/help")) { // Try to attach to the console bool attachedToConsole = Kernel32.AttachConsole(Kernel32.ATTACHCONSOLE_ATTACHPARENTPROCESS); // If attach didn't work, open a console if (!attachedToConsole) { Kernel32.AllocConsole(); } StringBuilder helpOutput = new StringBuilder(); helpOutput.AppendLine(); helpOutput.AppendLine("Greenshot commandline options:"); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t/help"); helpOutput.AppendLine("\t\tThis help."); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t/exit"); helpOutput.AppendLine("\t\tTries to close all running instances."); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t/reload"); helpOutput.AppendLine("\t\tReload the configuration of Greenshot."); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t/language [language code]"); helpOutput.AppendLine("\t\tSet the language of Greenshot, e.g. greenshot /language en-US."); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t[filename]"); helpOutput.AppendLine("\t\tOpen the bitmap files in the running Greenshot instance or start a new instance"); Console.WriteLine(helpOutput.ToString()); // If attach didn't work, wait for key otherwise the console will close to quickly if (!attachedToConsole) { Console.ReadKey(); } FreeMutex(); return; } if (argument.ToLower().Equals("/exit")) { // unregister application on uninstall (allow uninstall) try { LOG.Info("Sending all instances the exit command."); // Pass Exit to running instance, if any SendData(new CopyDataTransport(CommandEnum.Exit)); } catch (Exception e) { LOG.Warn("Exception by exit.", e); } FreeMutex(); return; } // Reload the configuration if (argument.ToLower().Equals("/reload")) { // Modify configuration LOG.Info("Reloading configuration!"); // Update running instances SendData(new CopyDataTransport(CommandEnum.ReloadConfig)); FreeMutex(); return; } // Stop running if (argument.ToLower().Equals("/norun")) { // Make an exit possible FreeMutex(); return; } // Language if (argument.ToLower().Equals("/language")) { conf.Language = args[++argumentNr]; IniConfig.Save(); continue; } // Files to open filesToOpen.Add(argument); } // Finished parsing the command line arguments, see if we need to do anything CopyDataTransport transport = new CopyDataTransport(); if (filesToOpen.Count > 0) { foreach (string fileToOpen in filesToOpen) { transport.AddCommand(CommandEnum.OpenFile, fileToOpen); } } if (MainForm.instance == null) MainForm.instance = new MainForm(transport); // if language is not set, show language dialog if (string.IsNullOrEmpty(conf.Language)) { LanguageDialog languageDialog = LanguageDialog.GetInstance(); languageDialog.ShowDialog(); conf.Language = languageDialog.SelectedLanguage; IniConfig.Save(); } // Check if it's the first time launch? if (conf.IsFirstLaunch) { conf.IsFirstLaunch = false; IniConfig.Save(); transport.AddCommand(CommandEnum.FirstLaunch); } } catch (Exception ex) { LOG.Error("Exception in startup.", ex); Application_ThreadException(MainForm.ActiveForm, new ThreadExceptionEventArgs(ex)); } }
/// <summary> /// Send DataTransport Object via Window-messages /// </summary> /// <param name="dataTransport">DataTransport with data for a running instance</param> private static void SendData(CopyDataTransport dataTransport) { string appName = Application.ProductName; CopyData copyData = new CopyData(); copyData.Channels.Add(appName); copyData.Channels[appName].Send(dataTransport); }
public MainForm(CopyDataTransport dataTransport) { _instance = this; // // The InitializeComponent() call is required for Windows Forms designer support. // try { InitializeComponent(); } catch (ArgumentException ex) { // Added for Bug #1420, this doesn't solve the issue but maybe the user can do something with it. ex.Data.Add("more information here", "http://support.microsoft.com/kb/943140"); throw; } notifyIcon.Icon = GreenshotResources.getGreenshotIcon(); Icon = GreenshotResources.getGreenshotIcon(); // Disable access to the settings, for feature #3521446 contextmenu_settings.Visible = !_conf.DisableSettings; // Make sure all hotkeys pass this window! HotkeyControl.RegisterHotkeyHWND(Handle); RegisterHotkeys(); new ToolTip(); UpdateUI(); // This forces the registration of all destinations inside Greenshot itself. DestinationHelper.GetAllDestinations(); // This forces the registration of all processors inside Greenshot itself. ProcessorHelper.GetAllProcessors(); // Load all the plugins PluginHelper.Instance.LoadPlugins(); // Check destinations, remove all that don't exist foreach(string destination in _conf.OutputDestinations.ToArray()) { if (DestinationHelper.GetDestination(destination) == null) { _conf.OutputDestinations.Remove(destination); } } // we should have at least one! if (_conf.OutputDestinations.Count == 0) { _conf.OutputDestinations.Add(EditorDestination.DESIGNATION); } if (_conf.DisableQuickSettings) { contextmenu_quicksettings.Visible = false; } else { // Do after all plugins & finding the destination, otherwise they are missing! InitializeQuickSettingsMenu(); } SoundHelper.Initialize(); coreConfiguration.PropertyChanged += OnIconSizeChanged; OnIconSizeChanged(this, new PropertyChangedEventArgs("IconSize")); // Set the Greenshot icon visibility depending on the configuration. (Added for feature #3521446) // Setting it to true this late prevents Problems with the context menu notifyIcon.Visible = !_conf.HideTrayicon; // Make sure we never capture the mainform WindowDetails.RegisterIgnoreHandle(Handle); // Create a new instance of the class: copyData = new CopyData(); _copyData = new CopyData(); // Assign the handle: _copyData.AssignHandle(Handle); // Create the channel to send on: _copyData.Channels.Add("Greenshot"); // Hook up received event: _copyData.CopyDataReceived += CopyDataDataReceived; if (dataTransport != null) { HandleDataTransport(dataTransport); } // Make Greenshot use less memory after startup if (_conf.MinimizeWorkingSetSize) { PsAPI.EmptyWorkingSet(); } }
public static void Start(string[] args) { bool isAlreadyRunning = false; List<string> filesToOpen = new List<string>(); // Set the Thread name, is better than "1" Thread.CurrentThread.Name = Application.ProductName; // Init Log4NET LogFileLocation = LogHelper.InitializeLog4NET(); // Get logger LOG = LogManager.GetLogger(typeof(MainForm)); Application.ThreadException += Application_ThreadException; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; // Initialize the IniConfig IniConfig.Init(); // Log the startup LOG.Info("Starting: " + EnvironmentInfo.EnvironmentToString(false)); // Read configuration _conf = IniConfig.GetIniSection<CoreConfiguration>(); try { // Fix for Bug 2495900, Multi-user Environment // check whether there's an local instance running already try { // Added Mutex Security, hopefully this prevents the UnauthorizedAccessException more gracefully // See an example in Bug #3131534 SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); MutexSecurity mutexsecurity = new MutexSecurity(); mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.FullControl, AccessControlType.Allow)); mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.ChangePermissions, AccessControlType.Deny)); mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.Delete, AccessControlType.Deny)); bool created; // 1) Create Mutex _applicationMutex = new Mutex(false, @"Local\F48E86D3-E34C-4DB7-8F8F-9A0EA55F0D08", out created, mutexsecurity); // 2) Get the right to it, this returns false if it's already locked if (!_applicationMutex.WaitOne(0, false)) { LOG.Debug("Greenshot seems already to be running!"); isAlreadyRunning = true; // Clean up _applicationMutex.Close(); _applicationMutex = null; } } catch (AbandonedMutexException e) { // Another Greenshot instance didn't cleanup correctly! // we can ignore the exception, it happend on the "waitone" but still the mutex belongs to us LOG.Warn("Greenshot didn't cleanup correctly!", e); } catch (UnauthorizedAccessException e) { LOG.Warn("Greenshot is most likely already running for a different user in the same session, can't create mutex due to error: ", e); isAlreadyRunning = true; } catch (Exception e) { LOG.Warn("Problem obtaining the Mutex, assuming it was already taken!", e); isAlreadyRunning = true; } if (args.Length > 0 && LOG.IsDebugEnabled) { StringBuilder argumentString = new StringBuilder(); for(int argumentNr = 0; argumentNr < args.Length; argumentNr++) { argumentString.Append("[").Append(args[argumentNr]).Append("] "); } LOG.Debug("Greenshot arguments: " + argumentString); } for(int argumentNr = 0; argumentNr < args.Length; argumentNr++) { string argument = args[argumentNr]; // Help if (argument.ToLower().Equals("/help") || argument.ToLower().Equals("/h") || argument.ToLower().Equals("/?")) { // Try to attach to the console bool attachedToConsole = Kernel32.AttachConsole(Kernel32.ATTACHCONSOLE_ATTACHPARENTPROCESS); // If attach didn't work, open a console if (!attachedToConsole) { Kernel32.AllocConsole(); } StringBuilder helpOutput = new StringBuilder(); helpOutput.AppendLine(); helpOutput.AppendLine("Greenshot commandline options:"); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t/help"); helpOutput.AppendLine("\t\tThis help."); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t/exit"); helpOutput.AppendLine("\t\tTries to close all running instances."); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t/reload"); helpOutput.AppendLine("\t\tReload the configuration of Greenshot."); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t/language [language code]"); helpOutput.AppendLine("\t\tSet the language of Greenshot, e.g. greenshot /language en-US."); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t/inidirectory [directory]"); helpOutput.AppendLine("\t\tSet the directory where the greenshot.ini should be stored & read."); helpOutput.AppendLine(); helpOutput.AppendLine(); helpOutput.AppendLine("\t[filename]"); helpOutput.AppendLine("\t\tOpen the bitmap files in the running Greenshot instance or start a new instance"); Console.WriteLine(helpOutput.ToString()); // If attach didn't work, wait for key otherwise the console will close to quickly if (!attachedToConsole) { Console.ReadKey(); } FreeMutex(); return; } if (argument.ToLower().Equals("/exit")) { // unregister application on uninstall (allow uninstall) try { LOG.Info("Sending all instances the exit command."); // Pass Exit to running instance, if any SendData(new CopyDataTransport(CommandEnum.Exit)); } catch (Exception e) { LOG.Warn("Exception by exit.", e); } FreeMutex(); return; } // Reload the configuration if (argument.ToLower().Equals("/reload")) { // Modify configuration LOG.Info("Reloading configuration!"); // Update running instances SendData(new CopyDataTransport(CommandEnum.ReloadConfig)); FreeMutex(); return; } // Stop running if (argument.ToLower().Equals("/norun")) { // Make an exit possible FreeMutex(); return; } // Language if (argument.ToLower().Equals("/language")) { _conf.Language = args[++argumentNr]; IniConfig.Save(); continue; } // Setting the INI-directory if (argument.ToLower().Equals("/inidirectory")) { IniConfig.IniDirectory = args[++argumentNr]; continue; } // Files to open filesToOpen.Add(argument); } // Finished parsing the command line arguments, see if we need to do anything CopyDataTransport transport = new CopyDataTransport(); if (filesToOpen.Count > 0) { foreach(string fileToOpen in filesToOpen) { transport.AddCommand(CommandEnum.OpenFile, fileToOpen); } } if (isAlreadyRunning) { // We didn't initialize the language yet, do it here just for the message box if (filesToOpen.Count > 0) { SendData(transport); } else { StringBuilder instanceInfo = new StringBuilder(); bool matchedThisProcess = false; int index = 1; int currentProcessId; using (Process currentProcess = Process.GetCurrentProcess()) { currentProcessId = currentProcess.Id; } foreach (Process greenshotProcess in Process.GetProcessesByName("greenshot")) { try { instanceInfo.Append(index++ + ": ").AppendLine(Kernel32.GetProcessPath(greenshotProcess.Id)); if (currentProcessId == greenshotProcess.Id) { matchedThisProcess = true; } } catch (Exception ex) { LOG.Debug(ex); } greenshotProcess.Dispose(); } if (!matchedThisProcess) { using (Process currentProcess = Process.GetCurrentProcess()) { instanceInfo.Append(index + ": ").AppendLine(Kernel32.GetProcessPath(currentProcess.Id)); } } // A dirty fix to make sure the messagebox is visible as a Greenshot window on the taskbar using (Form dummyForm = new Form()) { dummyForm.Icon = GreenshotResources.getGreenshotIcon(); dummyForm.ShowInTaskbar = true; dummyForm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; dummyForm.Location = new Point(int.MinValue, int.MinValue); dummyForm.Load += delegate { dummyForm.Size = Size.Empty; }; dummyForm.Show(); MessageBox.Show(dummyForm, Language.GetString(LangKey.error_multipleinstances) + "\r\n" + instanceInfo, Language.GetString(LangKey.error), MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } FreeMutex(); Application.Exit(); return; } // From here on we continue starting Greenshot Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // if language is not set, show language dialog if(string.IsNullOrEmpty(_conf.Language)) { LanguageDialog languageDialog = LanguageDialog.GetInstance(); languageDialog.ShowDialog(); _conf.Language = languageDialog.SelectedLanguage; IniConfig.Save(); } // Check if it's the first time launch? if(_conf.IsFirstLaunch) { _conf.IsFirstLaunch = false; IniConfig.Save(); transport.AddCommand(CommandEnum.FirstLaunch); } // Should fix BUG-1633 Application.DoEvents(); _instance = new MainForm(transport); Application.Run(); } catch(Exception ex) { LOG.Error("Exception in startup.", ex); Application_ThreadException(ActiveForm, new ThreadExceptionEventArgs(ex)); } }
private void HandleDataTransport(CopyDataTransport dataTransport) { foreach(KeyValuePair<CommandEnum, string> command in dataTransport.Commands) { LOG.Debug("Data received, Command = " + command.Key + ", Data: " + command.Value); switch(command.Key) { case CommandEnum.Exit: LOG.Info("Exit requested"); Exit(); break; case CommandEnum.FirstLaunch: LOG.Info("FirstLaunch: Created new configuration, showing balloon."); try { notifyIcon.BalloonTipClicked += BalloonTipClicked; notifyIcon.BalloonTipClosed += BalloonTipClosed; notifyIcon.ShowBalloonTip(2000, "Greenshot", Language.GetFormattedString(LangKey.tooltip_firststart, HotkeyControl.GetLocalizedHotkeyStringFromString(_conf.RegionHotkey)), ToolTipIcon.Info); } catch (Exception ex) { LOG.Warn("Exception while showing first launch: ", ex); } break; case CommandEnum.ReloadConfig: LOG.Info("Reload requested"); try { IniConfig.Reload(); Invoke((MethodInvoker) delegate { // Even update language when needed UpdateUI(); // Update the hotkey // Make sure the current hotkeys are disabled HotkeyControl.UnregisterHotkeys(); RegisterHotkeys(); }); } catch (Exception ex) { LOG.Warn("Exception while reloading configuration: ", ex); } break; case CommandEnum.OpenFile: string filename = command.Value; LOG.InfoFormat("Open file requested: {0}", filename); if (File.Exists(filename)) { BeginInvoke((MethodInvoker)delegate { CaptureHelper.CaptureFile(filename); }); } else { LOG.Warn("No such file: " + filename); } break; default: LOG.Error("Unknown command!"); break; } } }
public MainForm(CopyDataTransport dataTransport) { instance = this; // // The InitializeComponent() call is required for Windows Forms designer support. // InitializeComponent(); lang = Language.GetInstance(); IniConfig.IniChanged += new FileSystemEventHandler(ReloadConfiguration); // Make sure all hotkeys pass this window! HotkeyControl.RegisterHotkeyHWND(this.Handle); RegisterHotkeys(); tooltip = new ToolTip(); UpdateUI(); InitializeQuickSettingsMenu(); captureForm = new CaptureForm(); // Load all the plugins PluginHelper.instance.LoadPlugins(this, captureForm); SoundHelper.Initialize(); // Enable the Greenshot icon to be visible, this prevents Problems with the context menu notifyIcon.Visible = true; // Create a new instance of the class: copyData = new CopyData(); copyData = new CopyData(); // Assign the handle: copyData.AssignHandle(this.Handle); // Create the channel to send on: copyData.Channels.Add("Greenshot"); // Hook up received event: copyData.CopyDataReceived += new CopyDataReceivedEventHandler(CopyDataDataReceived); if (dataTransport != null) { HandleDataTransport(dataTransport); } ClipboardHelper.RegisterClipboardViewer(this.Handle); }
private void HandleDataTransport(CopyDataTransport dataTransport) { foreach (KeyValuePair<CommandEnum, string> command in dataTransport.Commands) { LOG.Debug("Data received, Command = " + command.Key + ", Data: " + command.Value); switch (command.Key) { case CommandEnum.Exit: exit(); break; case CommandEnum.FirstLaunch: LOG.Info("FirstLaunch: Created new configuration, showing balloon."); try { MainForm.instance.notifyIcon.BalloonTipClicked += HandleBalloonTipClick; MainForm.instance.notifyIcon.BalloonTipClosed += CleanupBalloonTipClick; MainForm.instance.notifyIcon.ShowBalloonTip(2000, "espUrl", lang.GetFormattedString(LangKey.tooltip_firststart, HotkeyControl.GetLocalizedHotkeyStringFromString(conf.RegionHotkey)), ToolTipIcon.Info); } catch { } break; case CommandEnum.ReloadConfig: try { IniConfig.Reload(); ReloadConfiguration(null, null); } catch { } break; case CommandEnum.OpenFile: string filename = command.Value; if (File.Exists(filename)) { captureForm.MakeCapture(filename); } else { LOG.Warn("No such file: " + filename); } break; default: LOG.Error("Unknown command!"); break; } } }