using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor { /// <summary> /// App.xaml 的交互逻辑 /// </summary> public partial class App : Application { System.Threading.Mutex mutex; public App() { this.Startup += new StartupEventHandler(App_Startup); } static App() { configManager = new XmlConfigManager(Globals.PathOfUserFolder + "config.xml"); //workspaceConfigManager 是可以变化的,不需要在这里初始化。 } /// <summary> /// 这个事件用于处理 WPF 4.0版在对剪贴板操作时存在的 Bug。 /// 当剪贴板被其它程序占用(监视)时,WPF 4.0 就会出现异常。微软在.net 4.5中修正了这个问题。 /// 但为了 Windows XP 中也能使用本程序,我只能将.net 版本锁定在 4.0——这是WinXP最后能支持一个.net 版本。 /// /// 事实上,这个办法的原理是反复尝试向剪贴板进行操作,仍然可能造成UI假死,并不是个完美的解决方案。 /// 另,有人实测使用Clipboard.SetData()方法取代Clipboard.SetText()方法比较好用。 /// 这个还需要进一步测试。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { var comException = e.Exception as System.Runtime.InteropServices.COMException; if (comException != null && comException.ErrorCode == -2147221040)///OpenClipboard HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN)) e.Handled = true; } void App_Startup(object sender, StartupEventArgs e) { var unableDoubleInstanceText = App.ConfigManager.Get("UnableDoubleInstance"); if (string.IsNullOrWhiteSpace(unableDoubleInstanceText) || unableDoubleInstanceText.ToLower() == "true") { bool ret; mutex = new System.Threading.Mutex(true, Globals.AppName, out ret); if (!ret) { MessageBox.Show(" 已有一个程序实例运行!双开应用程序较容易造成正在编辑的文件版本混乱。\r\n 实在需要双开,请点击主界面【偏好】→【禁止双开应用程序】菜单项来解除限制。", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning); //这里不能用LMessageBox.Show()方法。因为该方法对主窗口有依赖性。 Environment.Exit(0); } } } private static bool unableDoubleInstance = false; /// <summary> /// 禁止应用程序双开。 /// 2017年9月9日,早就没有什么必要了。默认关闭就好。 /// </summary> public static bool UnableDoubleInstance { get { return unableDoubleInstance; } set { unableDoubleInstance = value; } } private static XmlConfigManager configManager; /// <summary> /// 用于保存配置的Xml配置管理器。 /// </summary> public static XmlConfigManager ConfigManager { get { return configManager; } } private static XmlConfigManager workspaceConfigManager = null; /// <summary> /// 工作区配置文件管理器。 /// </summary> public static XmlConfigManager WorkspaceConfigManager { get { if (workspaceConfigManager == null) { workspaceConfigManager = new XmlConfigManager(Globals.PathOfWorkspace + "Configure.xml"); } return workspaceConfigManager; } set { workspaceConfigManager = value; } } private void Application_Startup(object sender, StartupEventArgs e) { //★,注意,以后不能开发带多参数的功能;实在必须开发这样的功能,须别作处理。 Globals.args = e.Args; if (e.Args.Length > 0) { if (e.Args.Length > 1) { //if (e.Args[0].Contains(' ')) //{ // Globals.CmdParameterString = "\"" + e.Args[0] + "\""; //} //else Globals.CmdParameterString = e.Args[0]; //这个方案解决不了带空格的路径的问题。 StringBuilder sb = new StringBuilder(); foreach (var arg in e.Args) { sb.Append(arg); sb.Append(" "); } Globals.CmdParameterString = sb.ToString().Trim(new char[] { ' ' }); if(Globals.CmdParameterString.Contains(" ")) { Globals.CmdParameterString = "\"" + Globals.CmdParameterString + "\""; } } else Globals.CmdParameterString = e.Args[0]; } else Globals.CmdParameterString = ""; } } }