using System.Deployment.Application; using Microsoft.Win32; using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Security.AccessControl; namespace MediaBrowser.ClickOnce { /// /// Class ClickOnceHelper /// public class ClickOnceHelper { /// /// The uninstall string /// private const string UninstallString = "UninstallString"; /// /// The display name key /// private const string DisplayNameKey = "DisplayName"; /// /// The uninstall string file /// private const string UninstallStringFile = "UninstallString.bat"; /// /// The appref extension /// private const string ApprefExtension = ".appref-ms"; /// /// The uninstall registry key /// private readonly RegistryKey UninstallRegistryKey; /// /// Gets the location. /// /// The location. private static string Location { get { return Assembly.GetExecutingAssembly().Location; } } /// /// Gets a value indicating whether this instance is network deployed. /// /// true if this instance is network deployed; otherwise, false. public static bool IsNetworkDeployed { get { return ApplicationDeployment.IsNetworkDeployed; } } /// /// Gets the name of the publisher. /// /// The name of the publisher. public string PublisherName { get; private set; } /// /// Gets the name of the product. /// /// The name of the product. public string ProductName { get; private set; } /// /// Gets the uninstall file. /// /// The uninstall file. public string UninstallFile { get; private set; } /// /// Gets the name of the suite. /// /// The name of the suite. public string SuiteName { get; private set; } /// /// Initializes a new instance of the class. /// /// Name of the publisher. /// Name of the product. /// Name of the suite. public ClickOnceHelper(string publisherName, string productName, string suiteName) { PublisherName = publisherName; ProductName = productName; SuiteName = suiteName; var publisherFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), PublisherName); if (!Directory.Exists(publisherFolder)) { Directory.CreateDirectory(publisherFolder); } UninstallFile = Path.Combine(publisherFolder, UninstallStringFile); UninstallRegistryKey = GetUninstallRegistryKeyByProductName(ProductName); } /// /// Gets the shortcut path. /// /// System.String. private string GetShortcutPath() { var allProgramsPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs); var shortcutPath = Path.Combine(allProgramsPath, PublisherName); if (!string.IsNullOrEmpty(SuiteName)) { shortcutPath = Path.Combine(shortcutPath, SuiteName); } return Path.Combine(shortcutPath, ProductName) + ApprefExtension; } /// /// Gets the startup shortcut path. /// /// System.String. private string GetStartupShortcutPath() { var startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup); return Path.Combine(startupPath, ProductName) + ApprefExtension; } /// /// Adds the shortcut to startup. /// public void AddShortcutToStartup() { var startupPath = GetStartupShortcutPath(); if (!File.Exists(startupPath)) { File.Copy(GetShortcutPath(), startupPath); } } /// /// Removes the shortcut from startup. /// public void RemoveShortcutFromStartup() { var startupPath = GetStartupShortcutPath(); if (File.Exists(startupPath)) { File.Delete(startupPath); } } /// /// Updates the uninstall parameters. /// /// Name of the uninstaller file. public void UpdateUninstallParameters(string uninstallerFileName) { if (UninstallRegistryKey != null) { UpdateUninstallString(uninstallerFileName); } } /// /// Gets the name of the uninstall registry key by product. /// /// Name of the product. /// RegistryKey. private RegistryKey GetUninstallRegistryKeyByProductName(string productName) { var subKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall"); if (subKey == null) { return null; } return subKey.GetSubKeyNames() .Select(name => subKey.OpenSubKey(name, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.QueryValues | RegistryRights.ReadKey | RegistryRights.SetValue)) .Where(application => application != null) .FirstOrDefault(application => application.GetValueNames().Where(appKey => appKey.Equals(DisplayNameKey)).Any(appKey => application.GetValue(appKey).Equals(productName))); } /// /// Updates the uninstall string. /// /// Name of the uninstaller file. private void UpdateUninstallString(string uninstallerFileName) { var uninstallString = (string)UninstallRegistryKey.GetValue(UninstallString); if (!string.IsNullOrEmpty(UninstallFile) && uninstallString.StartsWith("rundll32.exe", StringComparison.OrdinalIgnoreCase)) { File.WriteAllText(UninstallFile, uninstallString); } var str = String.Format("\"{0}\" uninstall", Path.Combine(Path.GetDirectoryName(Location), uninstallerFileName)); UninstallRegistryKey.SetValue(UninstallString, str); } /// /// Uninstalls this instance. /// public void Uninstall() { RemoveShortcutFromStartup(); var uninstallString = File.ReadAllText(UninstallFile); new Process { StartInfo = { Arguments = uninstallString.Substring(uninstallString.IndexOf(" ", StringComparison.OrdinalIgnoreCase) + 1), FileName = uninstallString.Substring(0, uninstallString.IndexOf(" ", StringComparison.OrdinalIgnoreCase)), UseShellExecute = false } }.Start(); } /// /// Configures the click once startup. /// /// Name of the publisher. /// Name of the product. /// Name of the suite. /// if set to true [run at startup]. /// The uninstaller filename. public static void ConfigureClickOnceStartupIfInstalled(string publisherName, string productName, string suiteName, bool runAtStartup, string uninstallerFilename) { if (!ApplicationDeployment.IsNetworkDeployed) { return; } var clickOnceHelper = new ClickOnceHelper(publisherName, productName, suiteName); if (runAtStartup) { clickOnceHelper.UpdateUninstallParameters(uninstallerFilename); clickOnceHelper.AddShortcutToStartup(); } else { clickOnceHelper.RemoveShortcutFromStartup(); } } } }