private static void Install(Session Session, string ManifestFile, string ServerApplication, string ProgramDataFolder) { // Same code as for custom action InstallManifest in Waher.IoTGateway.Installers if (string.IsNullOrEmpty(ManifestFile)) { throw new Exception("Missing manifest file."); } if (string.IsNullOrEmpty(ServerApplication)) { throw new Exception("Missing server application."); } if (string.IsNullOrEmpty(ProgramDataFolder)) { ProgramDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "IoT Gateway"); Session.Log("Using default program data folder: " + ProgramDataFolder); } if (!File.Exists(ServerApplication)) { throw new Exception("Server application not found: " + ServerApplication); } Session.Log("Getting assembly name of server."); AssemblyName ServerName = AssemblyName.GetAssemblyName(ServerApplication); Session.Log("Server assembly name: " + ServerName.ToString()); string DepsJsonFileName; int i = ServerApplication.LastIndexOf('.'); if (i < 0) { DepsJsonFileName = ServerApplication; } else { DepsJsonFileName = ServerApplication.Substring(0, i); } DepsJsonFileName += ".deps.json"; Session.Log("deps.json file name: " + DepsJsonFileName); if (!File.Exists(DepsJsonFileName)) { throw new Exception("Invalid server executable. No corresponding deps.json file found."); } Session.Log("Opening " + DepsJsonFileName); string s = File.ReadAllText(DepsJsonFileName); Session.Log("Parsing " + DepsJsonFileName); if (!(JSON.Parse(s) is Dictionary <string, object> Deps)) { throw new Exception("Invalid deps.json file. Unable to install."); } Session.Log("Loading manifest file."); XmlDocument Manifest = new XmlDocument(); Manifest.Load(ManifestFile); XmlElement Module = Manifest["Module"]; string SourceFolder = Path.GetDirectoryName(ManifestFile); string AppFolder = Path.GetDirectoryName(ServerApplication); Session.Log("Source folder: " + SourceFolder); Session.Log("App folder: " + AppFolder); foreach (XmlNode N in Module.ChildNodes) { if (N is XmlElement E && E.LocalName == "Assembly") { string FileName = XML.Attribute(E, "fileName"); string SourceFileName = Path.Combine(SourceFolder, FileName); if (CopyFileIfNewer(Session, SourceFileName, Path.Combine(AppFolder, FileName), true)) { if (FileName.EndsWith(".dll", StringComparison.CurrentCultureIgnoreCase)) { string PdbFileName = FileName.Substring(0, FileName.Length - 4) + ".pdb"; if (File.Exists(PdbFileName)) { CopyFileIfNewer(Session, Path.Combine(SourceFolder, PdbFileName), Path.Combine(AppFolder, PdbFileName), false); } } } Assembly A = Assembly.LoadFrom(SourceFileName); AssemblyName AN = A.GetName(); if (Deps != null && Deps.TryGetValue("targets", out object Obj) && Obj is Dictionary <string, object> Targets) { foreach (KeyValuePair <string, object> P in Targets) { if (P.Value is Dictionary <string, object> Target) { foreach (KeyValuePair <string, object> P2 in Target) { if (P2.Key.StartsWith(ServerName.Name + "/") && P2.Value is Dictionary <string, object> App && App.TryGetValue("dependencies", out object Obj2) && Obj2 is Dictionary <string, object> Dependencies) { Dependencies[AN.Name] = AN.Version.ToString(); break; } } Dictionary <string, object> Dependencies2 = new Dictionary <string, object>(); foreach (AssemblyName Dependency in A.GetReferencedAssemblies()) { Dependencies2[Dependency.Name] = Dependency.Version.ToString(); } Dictionary <string, object> Runtime = new Dictionary <string, object>() { { Path.GetFileName(SourceFileName), new Dictionary <string, object>() } }; Target[AN.Name + "/" + AN.Version.ToString()] = new Dictionary <string, object>() { { "dependencies", Dependencies2 }, { "runtime", Runtime } }; } } } if (Deps != null && Deps.TryGetValue("libraries", out object Obj3) && Obj3 is Dictionary <string, object> Libraries) { foreach (KeyValuePair <string, object> P in Libraries) { if (P.Key.StartsWith(AN.Name + "/")) { Libraries.Remove(P.Key); break; } } Libraries[AN.Name + "/" + AN.Version.ToString()] = new Dictionary <string, object>() { { "type", "project" }, { "serviceable", false }, { "sha512", string.Empty } }; } } } if (SourceFolder == AppFolder) { Session.Log("Skipping copying of content. Source and application folders the same. Assuming content files are located where they should be."); } else { CopyContent(Session, SourceFolder, AppFolder, ProgramDataFolder, Module); } Session.Log("Encoding JSON"); s = JSON.Encode(Deps, true); Session.Log("Writing " + DepsJsonFileName); File.WriteAllText(DepsJsonFileName, s, Encoding.UTF8); }
private static void Uninstall(Session Session, string ManifestFile, string ServerApplication, string ProgramDataFolder, bool Remove) { // Same code as for custom action InstallManifest in Waher.IoTGateway.Installers if (string.IsNullOrEmpty(ManifestFile)) { throw new Exception("Missing manifest file."); } if (string.IsNullOrEmpty(ServerApplication)) { throw new Exception("Missing server application."); } if (string.IsNullOrEmpty(ProgramDataFolder)) { ProgramDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "IoT Gateway"); Session.Log("Using default program data folder: " + ProgramDataFolder); } if (!File.Exists(ServerApplication)) { throw new Exception("Server application not found: " + ServerApplication); } Session.Log("Getting assembly name of server."); AssemblyName ServerName = AssemblyName.GetAssemblyName(ServerApplication); Session.Log("Server assembly name: " + ServerName.ToString()); string DepsJsonFileName; int i = ServerApplication.LastIndexOf('.'); if (i < 0) { DepsJsonFileName = ServerApplication; } else { DepsJsonFileName = ServerApplication.Substring(0, i); } DepsJsonFileName += ".deps.json"; Session.Log("deps.json file name: " + DepsJsonFileName); if (!File.Exists(DepsJsonFileName)) { throw new Exception("Invalid server executable. No corresponding deps.json file found."); } Session.Log("Opening " + DepsJsonFileName); string s = File.ReadAllText(DepsJsonFileName); Session.Log("Parsing " + DepsJsonFileName); if (!(JSON.Parse(s) is Dictionary <string, object> Deps)) { throw new Exception("Invalid deps.json file. Unable to install."); } Session.Log("Loading manifest file."); XmlDocument Manifest = new XmlDocument(); Manifest.Load(ManifestFile); XmlElement Module = Manifest["Module"]; string AppFolder = Path.GetDirectoryName(ServerApplication); Session.Log("App folder: " + AppFolder); foreach (XmlNode N in Module.ChildNodes) { if (N is XmlElement E && E.LocalName == "Assembly") { string FileName = XML.Attribute(E, "fileName"); string AppFileName = Path.Combine(AppFolder, FileName); Assembly A = Assembly.LoadFrom(AppFileName); AssemblyName AN = A.GetName(); string Key = AN.Name + "/" + AN.Version.ToString(); if (Deps != null && Deps.TryGetValue("targets", out object Obj) && Obj is Dictionary <string, object> Targets) { Targets.Remove(Key); foreach (KeyValuePair <string, object> P in Targets) { if (P.Value is Dictionary <string, object> Target) { foreach (KeyValuePair <string, object> P2 in Target) { if (P2.Key.StartsWith(ServerName.Name + "/") && P2.Value is Dictionary <string, object> App && App.TryGetValue("dependencies", out object Obj2) && Obj2 is Dictionary <string, object> Dependencies) { Dependencies.Remove(AN.Name); break; } } } } } if (Deps != null && Deps.TryGetValue("libraries", out object Obj3) && Obj3 is Dictionary <string, object> Libraries) { foreach (KeyValuePair <string, object> P in Libraries) { if (P.Key.StartsWith(AN.Name + "/")) { Libraries.Remove(P.Key); break; } } } if (Remove) { RemoveFile(Session, AppFileName); if (FileName.EndsWith(".dll", StringComparison.CurrentCultureIgnoreCase)) { string PdbFileName = FileName.Substring(0, FileName.Length - 4) + ".pdb"; RemoveFile(Session, PdbFileName); } } } } Session.Log("Encoding JSON"); s = JSON.Encode(Deps, true); Session.Log("Writing " + DepsJsonFileName); File.WriteAllText(DepsJsonFileName, s, Encoding.UTF8); if (Path.GetDirectoryName(ManifestFile) == AppFolder) { RemoveFile(Session, ManifestFile); } }