/// <summary> /// Unpack zipped package stream /// </summary> /// <param name="sourceUrl"></param> /// <param name="packageZip">Zipped package stream</param> /// <param name="appRootFolder"></param> /// <param name="imageResourceFolder">Folder where app image will be created</param> /// <param name="replace">Replace existing app if any</param> /// <param name="config"></param> public static void Unpack(Stream packageZip, string sourceUrl, string storeUrl, string appRootFolder, string imageResourceFolder, out DeployedConfigFile config) { lock (PackageManager.locker) { if (packageZip == null) throw new ArgumentNullException("packageZip"); if (sourceUrl == null) throw new ArgumentNullException("sourceUrl"); if (storeUrl == null) throw new ArgumentNullException("storeUrl"); if (appRootFolder == null) throw new ArgumentNullException("appRootFolder"); string createdDestinationFolder = null; try { using (ZipArchive archive = new ZipArchive(packageZip, ZipArchiveMode.Read)) { // Get Configuration PackageConfigFile packageConfig; ReadConfiguration(archive, out packageConfig); // Validate configuration ValidateConfiguration(archive, packageConfig); // Prepare to extract package string destinationFolder = Path.Combine(appRootFolder, packageConfig.Namespace); destinationFolder = Path.Combine(destinationFolder, packageConfig.Channel); destinationFolder = Path.Combine(destinationFolder, packageConfig.Version); try { if (Directory.Exists(destinationFolder)) { throw new InvalidOperationException("Application already installed.", new InvalidOperationException(string.Format("Destination folder exists, {0}", destinationFolder))); } createdDestinationFolder = Utils.CreateDirectory(destinationFolder); // Extract package archive.ExtractToDirectory(destinationFolder); string imageUri = string.Empty; // Unpack app image to starcounter admin folder UnpackAppImage(archive, packageConfig, imageResourceFolder, out imageUri); // Create app configuration file //config = new DeployedConfigFile(); CreateConfig(packageConfig, sourceUrl, storeUrl, imageUri, out config); //Uri u = new Uri(sourceUrl); //if (u.IsFile) { // config.SourceID = string.Format("{0:X8}", u.LocalPath.GetHashCode()); //} //else { // config.SourceID = u.Segments[u.Segments.Length - 1]; //} //config.SourceUrl = sourceUrl; //config.ImageUri = imageUri; // Save Application configuration string configFile = Path.Combine(destinationFolder, config.Namespace + PackageManager.deployedConfigurationFileExtention); config.Save(configFile); } catch (Exception) { if (createdDestinationFolder != null) { Directory.Delete(createdDestinationFolder, true); } throw; } } } catch (InvalidDataException e) { throw new InvalidOperationException("Failed to install package, Invalid package format", e); } catch (Exception e) { throw new InvalidOperationException("Failed to install package, " + e.Message, e); } } }
/// <summary> /// Get installed App in a folder /// </summary> /// <param name="path"></param> /// <returns></returns> public static void GetInstalledApp(string id, string path, out DeployedConfigFile installedConfig) { installedConfig = null; IList<DeployedConfigFile> apps = GetInstallApps(path); foreach (DeployedConfigFile config in apps) { if (config.ID == id) { installedConfig = config; } } }
/// <summary> /// Create App configuration from package configuration /// </summary> /// <param name="packageConfig"></param> /// <param name="config"></param> private static void CreateConfig(PackageConfigFile packageConfig, string sourceUrl, string storeUrl, string imageUri, out DeployedConfigFile config) { // Create app configuration file config = new DeployedConfigFile(); config.Namespace = packageConfig.Namespace; config.Channel = packageConfig.Channel; config.Version = packageConfig.Version; config.AppName = packageConfig.AppName; config.Executable = packageConfig.Executable; config.ResourceFolder = packageConfig.ResourceFolder; config.DisplayName = packageConfig.DisplayName; config.Company = packageConfig.Company; config.Description = packageConfig.Description; config.Heading = packageConfig.Heading; config.VersionDate = packageConfig.VersionDate; Uri u = new Uri(sourceUrl); if (u.IsFile) { config.SourceID = string.Format("{0:X8}", u.LocalPath.GetHashCode()); } else { config.SourceID = u.Segments[u.Segments.Length - 1]; } config.SourceUrl = sourceUrl; Uri su = new Uri(storeUrl); if (su.IsFile) { config.StoreID = string.Format("{0:X8}", su.LocalPath.GetHashCode()); } else { config.StoreID = su.Segments[su.Segments.Length - 1]; } config.StoreUrl = storeUrl; config.ImageUri = imageUri; config.CanBeUninstalled = true; }
/// <summary> /// /// </summary> /// <param name="from"></param> /// <param name="sourceHost"></param> /// <param name="packageZip"></param> /// <param name="appRootFolder"></param> /// <param name="imageResourceFolder">Folder where app image will be created</param> /// <param name="config"></param> //public static void Upgrade(DeployedConfigFile from, string packageZip, string appRootFolder, string imageResourceFolder, out DeployedConfigFile config) { // lock (PackageManager.locker) { // PackageManager.Unpack(packageZip, appRootFolder, imageResourceFolder, out config); // PackageManager.Delete(from, imageResourceFolder); // } //} /// <summary> /// /// </summary> /// <param name="from"></param> /// <param name="sourceHost"></param> /// <param name="packageZip"></param> /// <param name="appRootFolder"></param> /// <param name="imageResourceFolder">Folder where app image will be created</param> /// <param name="config"></param> //public static void Upgrade(DeployedConfigFile from, string sourceHost, Stream packageZip, string appRootFolder, string imageResourceFolder, out DeployedConfigFile config) { // lock (PackageManager.locker) { // PackageManager.Unpack(packageZip, sourceHost, appRootFolder, imageResourceFolder, out config); // PackageManager.Delete(from, imageResourceFolder); // } //} /// <summary> /// Delete unpacked package /// </summary> /// <param name="config"></param> public static void Delete(DeployedConfigFile config, string imageResourceFolder) { lock (PackageManager.locker) { if (string.IsNullOrEmpty(config.File)) { throw new InvalidOperationException(string.Format("Failed to uninstall application, Missing folder settings.")); } string folder = Path.GetDirectoryName(config.File); if (!Directory.Exists(folder)) { throw new InvalidOperationException(string.Format("Failed to uninstall application, invalid folder path {0}", folder)); } config.Verify(); DirectoryInfo di = new DirectoryInfo(folder); di.Delete(true); // Remove version folder. // Delete app image string imageFile = Path.Combine(imageResourceFolder, config.ImageUri); if (File.Exists(imageFile)) { File.Delete(imageFile); } // Clean up empty folders DirectoryInfo channelFolder = di.Parent; if (Utils.IsDirectoryEmpty(channelFolder.FullName)) { channelFolder.Delete(); DirectoryInfo nameSpaceFolder = di.Parent.Parent; if (Utils.IsDirectoryEmpty(nameSpaceFolder.FullName)) { nameSpaceFolder.Delete(); } } } }
/// <summary> /// Install zipped package /// </summary> /// <param name="packageZip">Zipped package</param> /// <param name="appRootFolder"></param> /// <param name="imageResourceFolder">Folder where app image will be created</param> /// <param name="config"></param> public static void Unpack(string packageZip, string appRootFolder, string imageResourceFolder, out DeployedConfigFile config) { lock (PackageManager.locker) { if (!File.Exists(packageZip)) { throw new FileNotFoundException("Package not found", packageZip); } string sourceHost = new Uri(System.IO.Path.GetFullPath(packageZip)).AbsoluteUri; string storeUrl = string.Empty; using (FileStream fs = new FileStream(packageZip, FileMode.Open)) { Unpack(fs, sourceHost, storeUrl, appRootFolder, imageResourceFolder, out config); } } }
/// <summary> /// Read App config /// </summary> /// <param name="s"></param> /// <param name="config"></param> public static void ReadConfig(Stream s, out DeployedConfigFile config) { XmlSerializer ser = new XmlSerializer(typeof(DeployedConfigFile)); config = ser.Deserialize(s) as DeployedConfigFile; }
/// <summary> /// Read App Config /// </summary> /// <param name="file"></param> /// <param name="config"></param> public static void ReadConfig(string file, out DeployedConfigFile config) { using (FileStream fs = new FileStream(file, FileMode.Open)) { ReadConfig(fs, out config); config.File = file; } }