static void Main(string[] args) { try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //bring in settings from any previous version if (Settings.Default.NeedUpgrade) { //see http://stackoverflow.com/questions/3498561/net-applicationsettingsbase-should-i-call-upgrade-every-time-i-load Settings.Default.Upgrade(); Settings.Default.Reload(); Settings.Default.NeedUpgrade = false; Settings.Default.Save(); StartUpWithFirstOrNewVersionBehavior = true; } #if DEBUG using (new Analytics("sje2fq26wnnk8c2kzflf", RegistrationDialog.GetAnalyticsUserInfo(), true)) #else string feedbackSetting = System.Environment.GetEnvironmentVariable("FEEDBACK"); //default is to allow tracking var allowTracking = string.IsNullOrEmpty(feedbackSetting) || feedbackSetting.ToLower() == "yes" || feedbackSetting.ToLower() == "true"; using (new Analytics("c8ndqrrl7f0twbf2s6cv", RegistrationDialog.GetAnalyticsUserInfo(), allowTracking)) #endif { if (args.Length == 1 && args[0].ToLower().EndsWith(".bloompack")) { using (var dlg = new BloomPackInstallDialog(args[0])) { dlg.ShowDialog(); } return; } #if DEBUG //the exception you get when there is no other BLOOM is a pain when running debugger with break-on-exceptions if (args.Length > 1) Thread.Sleep(3000);//this is here for testing the --rename scenario where the previous run needs a chance to die before we continue, but we're not using the mutex becuase it's a pain when using the debugger #else if (!GrabMutexForBloom()) return; #endif OldVersionCheck(); SetUpErrorHandling(); _applicationContainer = new ApplicationContainer(); SetUpLocalization(); Logger.Init(); if ( args.Length == 1 && args[0].ToLower().EndsWith(".bloomcollection")) { Settings.Default.MruProjects.AddNewPath(args[0]); } if (args.Length > 0 && args[0] == "--rename") { try { var pathToNewCollection = CollectionSettings.RenameCollection(args[1], args[2]); //MessageBox.Show("Your collection has been renamed."); Settings.Default.MruProjects.AddNewPath(pathToNewCollection); } catch (ApplicationException error) { Palaso.Reporting.ErrorReport.NotifyUserOfProblem(error, error.Message); Environment.Exit(-1); } catch (Exception error) { Palaso.Reporting.ErrorReport.NotifyUserOfProblem(error,"Bloom could not finish renaming your collection folder. Restart your computer and try again."); Environment.Exit(-1); } } _earliestWeShouldCloseTheSplashScreen = DateTime.Now.AddSeconds(3); Settings.Default.Save(); Browser.SetUpXulRunner(); Application.Idle += Startup; L10NSharp.LocalizationManager.SetUILanguage(Settings.Default.UserInterfaceLanguage, false); try { Application.Run(); } catch (System.AccessViolationException nasty) { Logger.ShowUserATextFileRelatedToCatastrophicError(nasty); System.Environment.FailFast("AccessViolationException"); } Settings.Default.Save(); Logger.ShutDown(); if (_projectContext != null) _projectContext.Dispose(); } } finally { ReleaseMutexForBloom(); } }
static void Main(string[] args) { try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //bring in settings from any previous version if (Settings.Default.NeedUpgrade) { //see http://stackoverflow.com/questions/3498561/net-applicationsettingsbase-should-i-call-upgrade-every-time-i-load Settings.Default.Upgrade(); Settings.Default.Reload(); Settings.Default.NeedUpgrade = false; Settings.Default.Save(); StartUpWithFirstOrNewVersionBehavior = true; } #if DEBUG using (new Analytics("sje2fq26wnnk8c2kzflf", RegistrationDialog.GetAnalyticsUserInfo(), true)) #else string feedbackSetting = System.Environment.GetEnvironmentVariable("FEEDBACK"); //default is to allow tracking var allowTracking = string.IsNullOrEmpty(feedbackSetting) || feedbackSetting.ToLower() == "yes" || feedbackSetting.ToLower() == "true"; using (new Analytics("c8ndqrrl7f0twbf2s6cv", RegistrationDialog.GetAnalyticsUserInfo(), allowTracking)) #endif { if (args.Length == 1 && args[0].ToLower().EndsWith(".bloompack")) { using (var dlg = new BloomPackInstallDialog(args[0])) { dlg.ShowDialog(); } return; } #if !DEBUG //the exception you get when there is no other BLOOM is a pain when running debugger with break-on-exceptions if (!GrabMutexForBloom()) return; #endif OldVersionCheck(); SetUpErrorHandling(); _applicationContainer = new ApplicationContainer(); SetUpLocalization(); Logger.Init(); if (args.Length == 1 && args[0].ToLower().EndsWith(".bloomcollection")) { Settings.Default.MruProjects.AddNewPath(args[0]); } _earliestWeShouldCloseTheSplashScreen = DateTime.Now.AddSeconds(3); Settings.Default.Save(); Browser.SetUpXulRunner(); Application.Idle += Startup; L10NSharp.LocalizationManager.SetUILanguage(Settings.Default.UserInterfaceLanguage, false); try { Application.Run(); } catch (System.AccessViolationException nasty) { Logger.ShowUserATextFileRelatedToCatastrophicError(nasty); System.Environment.FailFast("AccessViolationException"); } Settings.Default.Save(); Logger.ShutDown(); if (_projectContext != null) _projectContext.Dispose(); } } finally { ReleaseMutexForBloom(); } }
/// <summary> /// This routine handles the old-style download requests which come as an order URL from BloomLibrary. /// Enhance: it's unfortunate that we have two command-line methods of downloading a book. However, they have /// rather different requirements: /// - this one displays a progress UI, the other doesn't. /// - this one must extract the URL from a bloom: url (which the library must produce with urlencoding), /// for the other, it's more convenient to pass an unencoded url /// - worse, this version typically goes on to fully launch Bloom; the other always shuts the program down /// when done. Thus, this version is much more tightly connected to the normal startup code. /// Note that we can't easily change the exact command line that this version deals with, because /// Bloom library generates that command line, and if we change what it generates, everyone running an /// older Bloom will be in trouble. /// Most of the core implementation of the download process is common. /// </summary> private static void HandleDownload(string order) { // We will start up just enough to download the book. This avoids the code that normally tries to keep only a single instance running. // There is probably a pathological case here where we are overwriting an existing template just as the main instance is trying to // do something with it. The time interval would be very short, because download uses a temp folder until it has the whole thing // and then copies (or more commonly moves) it over in one step, and making a book from a template involves a similarly short // step of copying the template to the new book. Hopefully users have (or will soon learn) enough sense not to // try to use a template while in the middle of downloading a new version. SetUpErrorHandling(); using(_applicationContainer = new ApplicationContainer()) { SetUpLocalization(); //JT please review: is this needed? InstallerSupport.MakeBloomRegistryEntries(args); BookDownloadSupport.EnsureDownloadFolderExists(); Browser.SetUpXulRunner(); Browser.XulRunnerShutdown += OnXulRunnerShutdown; LocalizationManager.SetUILanguage(Settings.Default.UserInterfaceLanguage, false); var transfer = new BookTransfer(new BloomParseClient(), ProjectContext.CreateBloomS3Client(), _applicationContainer.BookThumbNailer, new BookDownloadStartingEvent()) /*not hooked to anything*/; transfer.HandleBloomBookOrder(order); PathToBookDownloadedAtStartup = transfer.LastBookDownloadedPath; // BL-2143: Don't show download complete message if download was not successful if (!string.IsNullOrEmpty(PathToBookDownloadedAtStartup)) { var caption = LocalizationManager.GetString("Download.CompletedCaption", "Download complete"); var message = LocalizationManager.GetString("Download.Completed", @"Your download ({0}) is complete. You can see it in the 'Books from BloomLibrary.org' section of your Collections."); message = string.Format(message, Path.GetFileName(PathToBookDownloadedAtStartup)); MessageBox.Show(message, caption); } } }
static int Main(string[] args1) { Logger.Init(); CheckForCorruptUserConfig(); // Bloom has several command line scenarios, without a coherent system for them. // The following is how we will do things from now on, and things can be moved // into this as time allows. See CommandLineOptions.cs. if (args1.Length > 0 && new[] {"--help", "hydrate", "download", "getfonts"}.Contains(args1[0])) //restrict using the commandline parser to cases were it should work { #if !__MonoCS__ AttachConsole(-1); #endif var exitCode = CommandLine.Parser.Default.ParseArguments(args1, new[] {typeof (HydrateParameters), typeof (DownloadBookOptions), typeof (GetUsedFontsParameters)}) .MapResult( (HydrateParameters opts) => HandlePrepareCommandLine(opts), (DownloadBookOptions opts) => DownloadBookCommand.HandleSilentDownload(opts), (GetUsedFontsParameters opts) => GetUsedFontsCommand.Handle(opts), errors => { var code = 0; foreach(var error in errors) { if(!(error is HelpVerbRequestedError)) { Debug.WriteLine(error.ToString()); Console.WriteLine(error.ToString()); code = 1; } } return code; }); return exitCode; // we're done } //Debug.Fail("Attach Now"); try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); XWebBrowser.DefaultBrowserType = XWebBrowser.BrowserType.GeckoFx; var args = args1; if (SIL.PlatformUtilities.Platform.IsWindows) { OldVersionCheck(); } //bring in settings from any previous version if (Settings.Default.NeedUpgrade) { //see http://stackoverflow.com/questions/3498561/net-applicationsettingsbase-should-i-call-upgrade-every-time-i-load Settings.Default.Upgrade(); Settings.Default.Reload(); Settings.Default.NeedUpgrade = false; Settings.Default.MaximizeWindow = true; // this is needed to force this to be written to the file, where a user can find it to modify it by hand (our video maker) Settings.Default.Save(); StartUpWithFirstOrNewVersionBehavior = true; } if (IsInstallerLaunch(args)) { InstallerSupport.HandleSquirrelInstallEvent(args); // may exit program } // Needs to be AFTER HandleSquirrelInstallEvent, because that can happen when the program is launched by Update rather than // by the user. if (!Settings.Default.LicenseAccepted) { Browser.SetUpXulRunner(); using (var dlg = new LicenseDialog()) if (dlg.ShowDialog() != DialogResult.OK) return 1; Settings.Default.LicenseAccepted = true; Settings.Default.Save(); } #if !USING_CHORUS Settings.Default.ShowSendReceive = false; // in case someone turned it on before we disabled #endif #if DEBUG if (args.Length > 0) { // This allows us to debug things like interpreting a URL. MessageBox.Show("Attach debugger now"); } #endif // Ensures that registration settings for all channels of Bloom are stored in a common place, // so the user is not asked to register each independently. RegistrationSettingsProvider.SetProductName("Bloom"); Dictionary<string, string> propertiesThatGoWithEveryEvent = ErrorReport.GetStandardProperties(); propertiesThatGoWithEveryEvent.Remove("MachineName"); propertiesThatGoWithEveryEvent.Remove("UserName"); propertiesThatGoWithEveryEvent.Remove("UserDomainName"); propertiesThatGoWithEveryEvent.Add("channel", ApplicationUpdateSupport.ChannelName); #if DEBUG using( new DesktopAnalytics.Analytics("sje2fq26wnnk8c2kzflf", RegistrationDialog.GetAnalyticsUserInfo(), propertiesThatGoWithEveryEvent, false)) _supressRegistrationDialog = true; #else string feedbackSetting = System.Environment.GetEnvironmentVariable("FEEDBACK"); //default is to allow tracking var allowTracking = string.IsNullOrEmpty(feedbackSetting) || feedbackSetting.ToLowerInvariant() == "yes" || feedbackSetting.ToLowerInvariant() == "true"; _supressRegistrationDialog = _supressRegistrationDialog || !allowTracking; using (new DesktopAnalytics.Analytics("c8ndqrrl7f0twbf2s6cv", RegistrationDialog.GetAnalyticsUserInfo(), propertiesThatGoWithEveryEvent, allowTracking)) #endif { // do not show the registration dialog if bloom was started for a special purpose if (args.Length > 0) _supressRegistrationDialog = true; if (args.Length == 1 && args[0].ToLowerInvariant().EndsWith(".bloompack")) { SetUpErrorHandling(); using (_applicationContainer = new ApplicationContainer()) { SetUpLocalization(); var path = args[0]; // This allows local links to bloom packs. if (path.ToLowerInvariant().StartsWith("bloom://")) { path = path.Substring("bloom://".Length); if (!RobustFile.Exists(path)) { path = FileLocator.GetFileDistributedWithApplication(true, path); if (!RobustFile.Exists(path)) return 1; } } using (var dlg = new BloomPackInstallDialog(path)) { dlg.ShowDialog(); if (dlg.ExitWithoutRunningBloom) return 1; } } } if (IsBloomBookOrder(args)) { HandleDownload(args[0]); // If another instance is running, this one has served its purpose and can exit right away. Otherwise, // carry on with starting up normally. See https://silbloom.myjetbrains.com/youtrack/issue/BL-3822. if (!UniqueToken.AcquireTokenQuietly(_mutexId)) return 0; } else { // Check whether another instance of Bloom is running. That should happen only when downloading a book because // BloomLibrary starts a new Bloom process even when one is already running. But that is taken care of in the // other branch of this if/else. So quit if we find another instance of Bloom running at this point. // (A message will pop up to tell the user about this situation if it happens.) if (!UniqueToken.AcquireToken(_mutexId, "Bloom")) return 1; } OldVersionCheck(); SetUpErrorHandling(); using (_applicationContainer = new ApplicationContainer()) { if (args.Length == 2 && args[0].ToLowerInvariant() == "--upload") { // A special path to upload chunks of stuff. This is not currently documented and is not very robust. // - User must log in before running this // - For best results each bloom book needs to be part of a collection in its parent folder // - little error checking (e.g., we don't apply the usual constraints that a book must have title and licence info) SetUpLocalization(); Browser.SetUpXulRunner(); Browser.XulRunnerShutdown += OnXulRunnerShutdown; var transfer = new BookTransfer(new BloomParseClient(), ProjectContext.CreateBloomS3Client(), _applicationContainer.BookThumbNailer, new BookDownloadStartingEvent()) /*not hooked to anything*/; transfer.UploadFolder(args[1], _applicationContainer); return 1; } InstallerSupport.MakeBloomRegistryEntries(args); BookDownloadSupport.EnsureDownloadFolderExists(); SetUpLocalization(); if (args.Length == 1 && !IsInstallerLaunch(args)) { Debug.Assert(args[0].ToLowerInvariant().EndsWith(".bloomcollection")); // Anything else handled above. if (CollectionChoosing.OpenCreateCloneControl.ReportIfInvalidCollectionToEdit(args[0])) return 1; Settings.Default.MruProjects.AddNewPath(args[0]); } if (args.Length > 0 && args[0] == "--rename") { try { var pathToNewCollection = CollectionSettings.RenameCollection(args[1], args[2]); //MessageBox.Show("Your collection has been renamed."); Settings.Default.MruProjects.AddNewPath(pathToNewCollection); } catch (ApplicationException error) { SIL.Reporting.ErrorReport.NotifyUserOfProblem(error, error.Message); Environment.Exit(-1); } catch (Exception error) { SIL.Reporting.ErrorReport.NotifyUserOfProblem(error, "Bloom could not finish renaming your collection folder. Restart your computer and try again."); Environment.Exit(-1); } } Browser.SetUpXulRunner(); Browser.XulRunnerShutdown += OnXulRunnerShutdown; #if DEBUG StartDebugServer(); #endif if (!BloomIntegrityDialog.CheckIntegrity()) { Environment.Exit(-1); } LocalizationManager.SetUILanguage(Settings.Default.UserInterfaceLanguage, false); // BL-1258: sometimes the newly installed fonts are not available until after Bloom restarts // We don't even want to try to install fonts if we are installed by an admin for all users; // it will have been installed already as part of the allUsers install. if ((!InstallerSupport.SharedByAllUsers()) && FontInstaller.InstallFont("AndikaNewBasic")) return 1; Run(); } } } finally { // Check memory one final time for the benefit of developers. The user won't see anything. SIL.Windows.Forms.Reporting.MemoryManagement.CheckMemory(true, "Bloom finished and exiting", false); UniqueToken.ReleaseToken(); } return 0; }
public static void SetUpLocalization(ApplicationContainer applicationContainerSource = null) { var applicationContainer = _applicationContainer; if (applicationContainerSource != null) applicationContainer = applicationContainerSource; var installedStringFileFolder = FileLocator.GetDirectoryDistributedWithApplication(true,"localization"); if (installedStringFileFolder == null) { // nb do NOT try to localize this...it's a shame, but the problem we're reporting is that the localization data is missing! var msg = @"Bloom seems to be missing some of the files it needs to run. Please uninstall Bloom, then install it again. If that's doesn't fix things, please contact us by clicking the ""Details"" button below, and we'd be glad to help."; ErrorReport.NotifyUserOfProblem(new ApplicationException("Missing localization directory"), msg); // If the user insists on continuing after that, start up using the built-in English. // We need an LM, and it needs some folder of tmx files, though it can be empty. So make a fake one. // Ideally we would dispose this at some point, but I don't know when we safely can. Normally this should never happen, // so I'm not very worried. var fakeLocalDir = new TemporaryFolder("Bloom fake localization").FolderPath; applicationContainer.LocalizationManager = LocalizationManager.Create("en", "Bloom", "Bloom", Application.ProductVersion, fakeLocalDir, "SIL/Bloom", Resources.BloomIcon, "*****@*****.**", //the parameters that follow are namespace beginnings: "Bloom"); return; } try { applicationContainer.LocalizationManager = LocalizationManager.Create(Settings.Default.UserInterfaceLanguage, "Bloom", "Bloom", Application.ProductVersion, installedStringFileFolder, "SIL/Bloom", Resources.BloomIcon, "*****@*****.**", //the parameters that follow are namespace beginnings: "Bloom"); //We had a case where someone translated stuff into another language, and sent in their tmx. But their tmx had soaked up a bunch of string //from their various templates, which were not Bloom standard templates. So then someone else sitting down to localize bloom would be //faced with a bunch of string that made no sense to them, because they don't have those templates. //So for now, we only soak up new strings if it's a developer, and hope that the Commit process will be enough for them to realize "oh no, I //don't want to check that stuff in". #if DEBUG applicationContainer.LocalizationManager.CollectUpNewStringsDiscoveredDynamically = true; #else applicationContainer.LocalizationManager.CollectUpNewStringsDiscoveredDynamically = false; #endif var uiLanguage = LocalizationManager.UILanguageId;//just feeding this into subsequent creates prevents asking the user twice if the language of their os isn't one we have a tmx for var unusedGoesIntoStatic = LocalizationManager.Create(uiLanguage, "Palaso", "Palaso", /*review: this is just bloom's version*/Application.ProductVersion, installedStringFileFolder, "SIL/Bloom", Resources.BloomIcon, "*****@*****.**", "SIL"); Settings.Default.UserInterfaceLanguage = LocalizationManager.UILanguageId; } catch (Exception error) { //handle http://jira.palaso.org/issues/browse/BL-213 if (GetRunningBloomProcessCount() > 1) { ErrorReport.NotifyUserOfProblem("Whoops. There is another copy of Bloom already running while Bloom was trying to set up L10NSharp."); Environment.FailFast("Bloom couldn't set up localization"); } if (error.Message.Contains("Bloom.en.tmx")) { ErrorReport.NotifyUserOfProblem(error, "Sorry. Bloom is trying to set up your machine to use this new version, but something went wrong getting at the file it needs. If you restart your computer, all will be well."); Environment.FailFast("Bloom couldn't set up localization"); } //otherwise, we don't know what caused it. throw; } }