mirror of
https://github.com/ShareX/ShareX.git
synced 2024-09-30 01:07:21 +13:00
Fix single instance management
There was a race condition in ApplicationInstanceManager. Now we use Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase to do instance management properly.
This commit is contained in:
parent
87f5feef62
commit
be1b15b59f
7 changed files with 93 additions and 251 deletions
|
@ -293,8 +293,6 @@
|
||||||
<Compile Include="Printer\PrintTextHelper.cs" />
|
<Compile Include="Printer\PrintTextHelper.cs" />
|
||||||
<Compile Include="Helpers\RegistryHelpers.cs" />
|
<Compile Include="Helpers\RegistryHelpers.cs" />
|
||||||
<Compile Include="SettingsHelper.cs" />
|
<Compile Include="SettingsHelper.cs" />
|
||||||
<Compile Include="SingleInstanceApplication\ApplicationInstanceManager.cs" />
|
|
||||||
<Compile Include="SingleInstanceApplication\InstanceProxy.cs" />
|
|
||||||
<Compile Include="DebugHelper.cs" />
|
<Compile Include="DebugHelper.cs" />
|
||||||
<Compile Include="UpdateChecker\UpdateCheckerLabel.cs">
|
<Compile Include="UpdateChecker\UpdateCheckerLabel.cs">
|
||||||
<SubType>UserControl</SubType>
|
<SubType>UserControl</SubType>
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
#region License Information (GPL v3)
|
|
||||||
|
|
||||||
/*
|
|
||||||
ShareX - A program that allows you to take screenshots and share any file type
|
|
||||||
Copyright (C) 2007-2014 ShareX Developers
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endregion License Information (GPL v3)
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Runtime.Remoting;
|
|
||||||
using System.Runtime.Remoting.Channels;
|
|
||||||
using System.Runtime.Remoting.Channels.Ipc;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace SingleInstanceApplication
|
|
||||||
{
|
|
||||||
public static class ApplicationInstanceManager
|
|
||||||
{
|
|
||||||
[DebuggerStepThrough]
|
|
||||||
public static bool CreateSingleInstance(string name, EventHandler<InstanceCallbackEventArgs> callback)
|
|
||||||
{
|
|
||||||
string eventName = string.Format("{0}-{1}", Environment.MachineName, name);
|
|
||||||
|
|
||||||
InstanceProxy.IsFirstInstance = false;
|
|
||||||
InstanceProxy.CommandLineArgs = Environment.GetCommandLineArgs();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (EventWaitHandle eventWaitHandle = EventWaitHandle.OpenExisting(eventName))
|
|
||||||
{
|
|
||||||
UpdateRemoteObject(name);
|
|
||||||
|
|
||||||
if (eventWaitHandle != null) eventWaitHandle.Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
InstanceProxy.IsFirstInstance = true;
|
|
||||||
|
|
||||||
using (EventWaitHandle eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName))
|
|
||||||
{
|
|
||||||
ThreadPool.RegisterWaitForSingleObject(eventWaitHandle, WaitOrTimerCallback, callback, Timeout.Infinite, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
RegisterRemoteType(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return InstanceProxy.IsFirstInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool CreateSingleInstance(EventHandler<InstanceCallbackEventArgs> callback)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return CreateSingleInstance(Application.ProductName, callback);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UpdateRemoteObject(string uri)
|
|
||||||
{
|
|
||||||
IpcClientChannel clientChannel = new IpcClientChannel();
|
|
||||||
ChannelServices.RegisterChannel(clientChannel, true);
|
|
||||||
|
|
||||||
InstanceProxy proxy = Activator.GetObject(typeof(InstanceProxy), string.Format("ipc://{0}{1}/{1}", Environment.MachineName, uri)) as InstanceProxy;
|
|
||||||
|
|
||||||
if (proxy != null)
|
|
||||||
{
|
|
||||||
proxy.SetCommandLineArgs(InstanceProxy.IsFirstInstance, InstanceProxy.CommandLineArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
ChannelServices.UnregisterChannel(clientChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RegisterRemoteType(string uri)
|
|
||||||
{
|
|
||||||
IpcServerChannel serverChannel = new IpcServerChannel(Environment.MachineName + uri);
|
|
||||||
ChannelServices.RegisterChannel(serverChannel, true);
|
|
||||||
|
|
||||||
RemotingConfiguration.RegisterWellKnownServiceType(typeof(InstanceProxy), uri, WellKnownObjectMode.Singleton);
|
|
||||||
|
|
||||||
Process process = Process.GetCurrentProcess();
|
|
||||||
process.Exited += delegate
|
|
||||||
{
|
|
||||||
ChannelServices.UnregisterChannel(serverChannel);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void WaitOrTimerCallback(object state, bool timedOut)
|
|
||||||
{
|
|
||||||
EventHandler<InstanceCallbackEventArgs> callback = state as EventHandler<InstanceCallbackEventArgs>;
|
|
||||||
if (callback == null) return;
|
|
||||||
|
|
||||||
callback(state, new InstanceCallbackEventArgs(InstanceProxy.IsFirstInstance, InstanceProxy.CommandLineArgs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
#region License Information (GPL v3)
|
|
||||||
|
|
||||||
/*
|
|
||||||
ShareX - A program that allows you to take screenshots and share any file type
|
|
||||||
Copyright (C) 2007-2014 ShareX Developers
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endregion License Information (GPL v3)
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Security.Permissions;
|
|
||||||
|
|
||||||
namespace SingleInstanceApplication
|
|
||||||
{
|
|
||||||
[Serializable]
|
|
||||||
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
|
|
||||||
internal class InstanceProxy : MarshalByRefObject
|
|
||||||
{
|
|
||||||
public static bool IsFirstInstance { get; internal set; }
|
|
||||||
|
|
||||||
public static string[] CommandLineArgs { get; internal set; }
|
|
||||||
|
|
||||||
public void SetCommandLineArgs(bool isFirstInstance, string[] commandLineArgs)
|
|
||||||
{
|
|
||||||
IsFirstInstance = isFirstInstance;
|
|
||||||
CommandLineArgs = commandLineArgs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class InstanceCallbackEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
internal InstanceCallbackEventArgs(bool isFirstInstance, string[] commandLineArgs)
|
|
||||||
{
|
|
||||||
IsFirstInstance = isFirstInstance;
|
|
||||||
CommandLineArgs = commandLineArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsFirstInstance { get; private set; }
|
|
||||||
|
|
||||||
public string[] CommandLineArgs { get; private set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -41,7 +41,7 @@ namespace ShareX
|
||||||
{
|
{
|
||||||
public partial class MainForm : HotkeyForm
|
public partial class MainForm : HotkeyForm
|
||||||
{
|
{
|
||||||
public bool IsReady { get; private set; }
|
public ManualResetEvent ReadyWaitHandle { get; private set; }
|
||||||
|
|
||||||
private bool forceClose;
|
private bool forceClose;
|
||||||
private UploadInfoManager uim;
|
private UploadInfoManager uim;
|
||||||
|
@ -49,6 +49,7 @@ public partial class MainForm : HotkeyForm
|
||||||
|
|
||||||
public MainForm()
|
public MainForm()
|
||||||
{
|
{
|
||||||
|
ReadyWaitHandle = new ManualResetEvent(false);
|
||||||
InitControls();
|
InitControls();
|
||||||
HandleCreated += MainForm_HandleCreated;
|
HandleCreated += MainForm_HandleCreated;
|
||||||
}
|
}
|
||||||
|
@ -62,7 +63,7 @@ private void MainForm_HandleCreated(object sender, EventArgs e)
|
||||||
AutoCheckUpdate();
|
AutoCheckUpdate();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IsReady = true;
|
ReadyWaitHandle.Set();
|
||||||
|
|
||||||
DebugHelper.WriteLine("Startup time: {0} ms", Program.StartTimer.ElapsedMilliseconds);
|
DebugHelper.WriteLine("Startup time: {0} ms", Program.StartTimer.ElapsedMilliseconds);
|
||||||
|
|
||||||
|
@ -675,7 +676,7 @@ private void MainForm_Resize(object sender, EventArgs e)
|
||||||
|
|
||||||
private void MainForm_LocationChanged(object sender, EventArgs e)
|
private void MainForm_LocationChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (IsReady && WindowState == FormWindowState.Normal)
|
if (ReadyWaitHandle.WaitOne(0) && WindowState == FormWindowState.Normal)
|
||||||
{
|
{
|
||||||
Program.Settings.MainFormPosition = Location;
|
Program.Settings.MainFormPosition = Location;
|
||||||
}
|
}
|
||||||
|
@ -683,7 +684,7 @@ private void MainForm_LocationChanged(object sender, EventArgs e)
|
||||||
|
|
||||||
private void MainForm_SizeChanged(object sender, EventArgs e)
|
private void MainForm_SizeChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (IsReady && WindowState == FormWindowState.Normal)
|
if (ReadyWaitHandle.WaitOne(0) && WindowState == FormWindowState.Normal)
|
||||||
{
|
{
|
||||||
Program.Settings.MainFormSize = Size;
|
Program.Settings.MainFormSize = Size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ You should have received a copy of the GNU General Public License
|
||||||
#endregion License Information (GPL v3)
|
#endregion License Information (GPL v3)
|
||||||
|
|
||||||
using HelpersLib;
|
using HelpersLib;
|
||||||
using SingleInstanceApplication;
|
using Microsoft.VisualBasic.ApplicationServices;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -32,6 +32,7 @@ You should have received a copy of the GNU General Public License
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using UploadersLib;
|
using UploadersLib;
|
||||||
|
|
||||||
|
@ -228,7 +229,6 @@ public static string Title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsMultiInstance { get; private set; }
|
|
||||||
public static bool IsPortable { get; private set; }
|
public static bool IsPortable { get; private set; }
|
||||||
public static bool IsSilentRun { get; private set; }
|
public static bool IsSilentRun { get; private set; }
|
||||||
public static bool IsSandbox { get; private set; }
|
public static bool IsSandbox { get; private set; }
|
||||||
|
@ -247,6 +247,8 @@ public static string Title
|
||||||
public static HotkeyManager HotkeyManager { get; set; }
|
public static HotkeyManager HotkeyManager { get; set; }
|
||||||
public static WatchFolderManager WatchFolderManager { get; set; }
|
public static WatchFolderManager WatchFolderManager { get; set; }
|
||||||
|
|
||||||
|
private static ShareXApplicationBase _appBase;
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
private static void Main(string[] args)
|
private static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
@ -255,17 +257,18 @@ private static void Main(string[] args)
|
||||||
|
|
||||||
StartTimer = Stopwatch.StartNew();
|
StartTimer = Stopwatch.StartNew();
|
||||||
|
|
||||||
IsMultiInstance = CLIHelper.CheckArgs(args, "multi", "m");
|
bool isMultiInstance = CLIHelper.CheckArgs(args, "multi", "m");
|
||||||
|
_appBase = new ShareXApplicationBase(!isMultiInstance);
|
||||||
if (IsMultiInstance || ApplicationInstanceManager.CreateSingleInstance(SingleInstanceCallback))
|
_appBase.Startup += StartupHandler;
|
||||||
{
|
_appBase.StartupNextInstance += StartupNextInstanceHandler;
|
||||||
Run(args);
|
_appBase.Shutdown += ShutdownHandler;
|
||||||
}
|
_appBase.Run(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Run(string[] args)
|
private static void StartupHandler(object sender, StartupEventArgs e)
|
||||||
{
|
{
|
||||||
string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
|
string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
|
||||||
|
string[] args = Environment.GetCommandLineArgs();
|
||||||
|
|
||||||
using (Mutex mutex = new Mutex(false, appGuid)) // Required for installer
|
using (Mutex mutex = new Mutex(false, appGuid)) // Required for installer
|
||||||
{
|
{
|
||||||
|
@ -291,9 +294,6 @@ private static void Run(string[] args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.EnableVisualStyles();
|
|
||||||
Application.SetCompatibleTextRenderingDefault(false);
|
|
||||||
|
|
||||||
DebugHelper.WriteLine("{0} started", Title);
|
DebugHelper.WriteLine("{0} started", Title);
|
||||||
DebugHelper.WriteLine("Operating system: " + Environment.OSVersion.VersionString);
|
DebugHelper.WriteLine("Operating system: " + Environment.OSVersion.VersionString);
|
||||||
DebugHelper.WriteLine("Command line: " + Environment.CommandLine);
|
DebugHelper.WriteLine("Command line: " + Environment.CommandLine);
|
||||||
|
@ -312,24 +312,64 @@ private static void Run(string[] args)
|
||||||
|
|
||||||
DebugHelper.WriteLine("MainForm init started");
|
DebugHelper.WriteLine("MainForm init started");
|
||||||
MainForm = new MainForm();
|
MainForm = new MainForm();
|
||||||
|
_appBase.MainForm = MainForm;
|
||||||
DebugHelper.WriteLine("MainForm init finished");
|
DebugHelper.WriteLine("MainForm init finished");
|
||||||
|
|
||||||
if (Settings == null)
|
if (Settings == null)
|
||||||
{
|
{
|
||||||
SettingsResetEvent.WaitOne();
|
SettingsResetEvent.WaitOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.Run(MainForm);
|
|
||||||
|
|
||||||
if (WatchFolderManager != null) WatchFolderManager.Dispose();
|
|
||||||
SaveSettings();
|
|
||||||
BackupSettings();
|
|
||||||
|
|
||||||
DebugHelper.WriteLine("ShareX closing");
|
|
||||||
DebugHelper.Logger.SaveLog(LogsFilePath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void StartupNextInstanceHandler(object sender, StartupNextInstanceEventArgs e)
|
||||||
|
{
|
||||||
|
e.BringToForeground = false;
|
||||||
|
string[] args = new string[e.CommandLine.Count + 1];
|
||||||
|
args[0] = "";
|
||||||
|
e.CommandLine.CopyTo(args, 1);
|
||||||
|
if (MainForm.ReadyWaitHandle.WaitOne(0)) DoStartupNextInstance(args);
|
||||||
|
else Task.Factory.StartNew(WaitFormLoad, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WaitFormLoad(object args)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (MainForm.ReadyWaitHandle.WaitOne(5000)) {
|
||||||
|
MainForm.Invoke(new Action<string[]>(DoStartupNextInstance), args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoStartupNextInstance(string[] args)
|
||||||
|
{
|
||||||
|
if (args == null || args.Length <= 1) {
|
||||||
|
if (MainForm.niTray != null && MainForm.niTray.Visible) {
|
||||||
|
// Workaround for Windows startup tray icon bug
|
||||||
|
MainForm.niTray.Visible = false;
|
||||||
|
MainForm.niTray.Visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainForm.ShowActivate();
|
||||||
|
}
|
||||||
|
else if (MainForm.Visible) {
|
||||||
|
MainForm.ShowActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainForm.UseCommandLineArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ShutdownHandler(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (WatchFolderManager != null) WatchFolderManager.Dispose();
|
||||||
|
SaveSettings();
|
||||||
|
BackupSettings();
|
||||||
|
|
||||||
|
DebugHelper.WriteLine("ShareX closing");
|
||||||
|
DebugHelper.Logger.SaveLog(LogsFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
public static void LoadSettings()
|
public static void LoadSettings()
|
||||||
{
|
{
|
||||||
LoadProgramSettings();
|
LoadProgramSettings();
|
||||||
|
@ -435,7 +475,7 @@ private static void Application_ThreadException(object sender, ThreadExceptionEv
|
||||||
OnError(e.Exception);
|
OnError(e.Exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
private static void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
OnError((Exception)e.ExceptionObject);
|
OnError((Exception)e.ExceptionObject);
|
||||||
}
|
}
|
||||||
|
@ -448,49 +488,6 @@ private static void OnError(Exception e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SingleInstanceCallback(object sender, InstanceCallbackEventArgs args)
|
|
||||||
{
|
|
||||||
if (WaitFormLoad(5000))
|
|
||||||
{
|
|
||||||
Action d = () =>
|
|
||||||
{
|
|
||||||
if (args.CommandLineArgs == null || args.CommandLineArgs.Length <= 1)
|
|
||||||
{
|
|
||||||
if (MainForm.niTray != null && MainForm.niTray.Visible)
|
|
||||||
{
|
|
||||||
// Workaround for Windows startup tray icon bug
|
|
||||||
MainForm.niTray.Visible = false;
|
|
||||||
MainForm.niTray.Visible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainForm.ShowActivate();
|
|
||||||
}
|
|
||||||
else if (MainForm.Visible)
|
|
||||||
{
|
|
||||||
MainForm.ShowActivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
MainForm.UseCommandLineArgs(args.CommandLineArgs);
|
|
||||||
};
|
|
||||||
|
|
||||||
MainForm.InvokeSafe(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool WaitFormLoad(int wait)
|
|
||||||
{
|
|
||||||
Stopwatch timer = Stopwatch.StartNew();
|
|
||||||
|
|
||||||
while (timer.ElapsedMilliseconds < wait)
|
|
||||||
{
|
|
||||||
if (MainForm != null && MainForm.IsReady) return true;
|
|
||||||
|
|
||||||
Thread.Sleep(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ConfigureUploadersConfigWatcher()
|
public static void ConfigureUploadersConfigWatcher()
|
||||||
{
|
{
|
||||||
if (Program.Settings.DetectUploaderConfigFileChanges && uploaderConfigWatcher == null)
|
if (Program.Settings.DetectUploaderConfigFileChanges && uploaderConfigWatcher == null)
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\MegaApiClient.1.0.4\lib\MegaApiClient.dll</HintPath>
|
<HintPath>..\packages\MegaApiClient.1.0.4\lib\MegaApiClient.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.VisualBasic" />
|
||||||
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\Newtonsoft.Json.6.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.6.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
|
@ -227,6 +228,7 @@
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Resources.resx</DependentUpon>
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="ShareXApplicationBase.cs" />
|
||||||
<Compile Include="TaskHelpers.cs" />
|
<Compile Include="TaskHelpers.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|
24
ShareX/ShareXApplicationBase.cs
Normal file
24
ShareX/ShareXApplicationBase.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
using Microsoft.VisualBasic.ApplicationServices;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace ShareX
|
||||||
|
{
|
||||||
|
class ShareXApplicationBase : WindowsFormsApplicationBase
|
||||||
|
{
|
||||||
|
public ShareXApplicationBase(bool isSingleInstance)
|
||||||
|
{
|
||||||
|
IsSingleInstance = isSingleInstance;
|
||||||
|
EnableVisualStyles = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public new Form MainForm
|
||||||
|
{
|
||||||
|
get { return base.MainForm; }
|
||||||
|
set { base.MainForm = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue