public static ActionResult CheckApplicationExists(Session session) { var deploymentManifest = new Uri(session["DeploymentManifest"]); var downloadTask = (Task<GetManifestCompletedEventArgs>)null; using(var host = new InPlaceHostingManager(deploymentManifest, false)) { downloadTask = host.DownloadManifestAsync(); downloadTask.Wait(); if(downloadTask.IsCanceled) { return ActionResult.UserExit; } else if(downloadTask.IsFaulted) { session.Message(InstallMessage.Error, new Record { FormatString = downloadTask.Exception.ToString() }); return ActionResult.Failure; } var manifest = downloadTask.Result; var result = manifest.ApplicationManifest.CheckApplicationExists(); if(result == ActionResult.SkipRemainingActions) { session.Log("{0} is already installed.", manifest.ProductName); } return result; } }
public void InstallApplication(string deployManifestUriStr) { try { Uri deploymentUri = new Uri(deployManifestUriStr); iphm = new InPlaceHostingManager(deploymentUri, false); } catch (UriFormatException uriEx) { MessageBox.Show("Cannot install the application: " + "The deployment manifest URL supplied is not a valid URL. " + "Error: " + uriEx.Message); return; } catch (PlatformNotSupportedException platformEx) { MessageBox.Show("Cannot install the application: " + "This program requires Windows XP or higher. " + "Error: " + platformEx.Message); return; } catch (ArgumentException argumentEx) { MessageBox.Show("Cannot install the application: " + "The deployment manifest URL supplied is not a valid URL. " + "Error: " + argumentEx.Message); return; } iphm.GetManifestCompleted += new EventHandler<GetManifestCompletedEventArgs>(iphm_GetManifestCompleted); iphm.GetManifestAsync(); }
public async Task InstallClickOnceApp(Uri deploymentUri) { using (var host = new InPlaceHostingManager(deploymentUri, false)) { await GetApplicationManifest(host); AssertApplicationRequirements(host); await DownloadApplication(host); } }
/// <summary>Removes a previously installed user-defined component of an application.</summary> /// <param name="subscriptionId">A string that contains a subscription identifier, which indicates the add-in to remove.</param> /// <exception cref="T:System.ArgumentException"> /// <paramref name="subscriptionId" /> is not a valid subscription identity, or does not include a name, public key token, processor architecture, and version number.</exception> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="subscriptionId" /> is null.</exception> public static void UninstallCustomAddIn(string subscriptionId) { DefinitionIdentity subIdAndValidate = InPlaceHostingManager.GetSubIdAndValidate(subscriptionId); SubscriptionStore currentUser = SubscriptionStore.CurrentUser; currentUser.RefreshStorePointer(); SubscriptionState subscriptionState = currentUser.GetSubscriptionState(subIdAndValidate); subscriptionState.SubscriptionStore.UninstallCustomHostSpecifiedSubscription(subscriptionState); }
public static ActionResult DownloadApplication(Session session) { var deploymentManifest = new Uri(session["DeploymentManifest"]); var cancellationTokenSource = new CancellationTokenSource(); var previousProgressPercentage = 0; var downloadTask = (Task)null; DisplayActionData(session, "Hello, World!"); ResetProgress(session); using(var host = new InPlaceHostingManager(deploymentManifest, false)) { downloadTask = host.DownloadManifestAsync(); downloadTask.Wait(); if(downloadTask.IsCanceled) { return ActionResult.UserExit; } else if(downloadTask.IsFaulted) { session.Message(InstallMessage.Error, new Record { FormatString = downloadTask.Exception.ToString() }); return ActionResult.Failure; } // Requirements host.AssertApplicationRequirements(true); // Download downloadTask = host.DownloadApplicationAsync(progress => { session.Log("Downloaded {0,10}", (((double)progress.ProgressPercentage) / 100d).ToString("P")); IncrementProgress(session, progress.ProgressPercentage - previousProgressPercentage); previousProgressPercentage = progress.ProgressPercentage; }); downloadTask.Wait(); if(downloadTask.IsCanceled) { return ActionResult.UserExit; } else if(downloadTask.IsFaulted) { session.Message(InstallMessage.Error, new Record { FormatString = downloadTask.Exception.ToString() }); return ActionResult.Failure; } } return ActionResult.Success; }
private static Task GetApplicationManifest(InPlaceHostingManager host) { var completion = new TaskCompletionSource<int>(); host.GetManifestCompleted += (sender, e) => { if (e.Error != null) { completion.SetException(e.Error); } else { completion.SetResult(0); } }; host.GetManifestAsync(); return completion.Task; }
private void TryUriActivation() { if(_hasTriedUriActivation) { Shutdown(); } else { _hasTriedUriActivation = true; EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordHosting | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info, EventTrace.Event.WpfHost_FirstTimeActivation); // IPHM created on a worker thread. See threading comment on _hostingManager. ThreadStart d = delegate { _hostingManager = new InPlaceHostingManager(_deploymentManifest); // Continue on the UI thread. Dispatcher.BeginInvoke(DispatcherPriority.Normal, new SendOrPostCallback(delegate { // Ordering is important here - downloading the manifest is done asynchronously // so can be started before we spend time setting up the UI. This saves us some // time - especially during cold-start scenarios. DoGetManifestAsync(); DoDownloadUI(); }), null); }; d.BeginInvoke(null, null); } }
//----------------------------------------------------- // // Internal Methods // //----------------------------------------------------- #region Internal Methods // Check if the platform exception is due to missing WinFX or CLR dependency // Parse the exception message and find out the dependent WinFX version and create the // corresponding fwlink Uri. static internal MissingDependencyType GetWinFXRequirement(Exception e, InPlaceHostingManager hostingManager, out string version, out Uri fwlinkUri) { version = String.Empty; fwlinkUri = null; // ClickOnce detects whether it's running as part of the v3.5 "client" subset ("Arrowhead") and // if so blocks older applications that don't explicitly opt into the subset framework. // (Unfortunately, it does not block an application targeting the full 3.5 SP1 framework this way.) // The exception message has ".NET Framework 3.5 SP1" hard-coded in it (referring to the version // of the framework needed to run the application, which is not strictly right, but older versions // can't/shouldn't be installed on top of the "client" subset). // To make this exception message parsing at least potentially somewhat future-proof, a regex is // used that allows for some variability of syntax and version number. // We don't include the "SP1" part in the fwlink query. This is for consistency with the detection // via sentinel assemblies. The server can be updated to offer the latest release/SP compatible // with the requested major.minor version. if (e is DependentPlatformMissingException) { Regex regex = new Regex(@".NET Framework (v\.?)?(?<version>\d{1,2}(\.\d{1,2})?)", RegexOptions.ExplicitCapture|RegexOptions.IgnoreCase); string msg = e.Message; Match match = regex.Match(msg); if(match.Success) { version = match.Groups[1].Value; ConstructFwlinkUrl(version, out fwlinkUri); return MissingDependencyType.WinFX; } } // Load the clickonce resource and use it to parse the exception message Assembly deploymentDll = Assembly.GetAssembly(hostingManager.GetType()); if (deploymentDll == null) { return MissingDependencyType.Others; } ResourceManager resourceManager = new ResourceManager("System.Deployment", deploymentDll); if (resourceManager == null) { return MissingDependencyType.Others; } String clrProductName = resourceManager.GetString("PlatformMicrosoftCommonLanguageRuntime", CultureInfo.CurrentUICulture); String versionString = resourceManager.GetString("PlatformDependentAssemblyVersion", CultureInfo.CurrentUICulture); if ((clrProductName == null) || (versionString == null)) { return MissingDependencyType.Others; } // Need to trim off the parameters in the ClickOnce strings: // "{0} Version {1}" -> "Version" // "Microsoft Common Language Runtime Version {0}" -> "Microsoft Common Language Runtime Version" clrProductName = clrProductName.Replace("{0}", ""); versionString = versionString.Replace("{0}", ""); versionString = versionString.Replace("{1}", ""); string[] sentinelAssemblies = { // The Original & "Only" "WindowsBase", // A reference to System.Core is what makes an application target .NET v3.5. // Because WindowsBase still has v3.0.0.0, it's not the one that fails the platform requirements // test when a v3.5 app is run on the v3 runtime. (This additional check added for v3 SP1.) "System.Core", // New sentinel assemblies for v3.5 SP1 (see the revision history) "Sentinel.v3.5Client", "System.Data.Entity" }; // Parse the required version and trim it to major and minor only string excpMsg = e.Message; int index = excpMsg.IndexOf(versionString, StringComparison.Ordinal); if (index != -1) { // ClickOnce exception message is ErrorMessage_Platform* // from clickonce/system.deployment.txt version = String.Copy(excpMsg.Substring(index + versionString.Length)); int indexToFirstDot = version.IndexOf(".", StringComparison.Ordinal); int indexToSecondDot = version.IndexOf(".", indexToFirstDot+1, StringComparison.Ordinal); // Defense in depth here in case Avalon change the version scheme to major + minor only // and we might never see the second dot if (indexToSecondDot != -1) { version = version.Substring(0, indexToSecondDot); } if (excpMsg.IndexOf(clrProductName, StringComparison.Ordinal) != -1) { // prepend CLR to distinguish CLR version fwlink query // vs. WinFX version query. string clrVersion = String.Concat("CLR", version); return (ConstructFwlinkUrl(clrVersion, out fwlinkUri) ? MissingDependencyType.CLR : MissingDependencyType.Others); } else { bool sentinelMissing = false; foreach (string sentinelAssembly in sentinelAssemblies) { if (excpMsg.IndexOf(sentinelAssembly, StringComparison.OrdinalIgnoreCase) > 0) { sentinelMissing = true; break; } } if (!sentinelMissing) { version = String.Empty; } } } return (ConstructFwlinkUrl(version, out fwlinkUri) ? MissingDependencyType.WinFX : MissingDependencyType.Others); }
private static void AssertApplicationRequirements(InPlaceHostingManager host) { host.AssertApplicationRequirements(true); }
private void InstallApplication(Uri app) { var manager = new InPlaceHostingManager(app, false); manager.GetManifestCompleted += new EventHandler<GetManifestCompletedEventArgs>( OnGetManifestCompleted ); // I would love to just "await manager.GetManifestAsync" here // but GetManifestAsync returns void _event = new AutoResetEvent(false); // Console.WriteLine("Getting manifest for {0}", app); manager.GetManifestAsync(); _event.WaitOne(); // this call is synchronous // Console.WriteLine("Asserting application requirements for {0}", app); manager.AssertApplicationRequirements(true); // Console.WriteLine("AssertApplicationRequirements passes"); manager.DownloadApplicationCompleted += new EventHandler<DownloadApplicationCompletedEventArgs>( OnDownloadApplicationCompleted ); // Console.WriteLine("Downloading and installing {0}", app); manager.DownloadApplicationAsync(); _event.WaitOne(); }