public void PlugInInfoCloneTest() { var pluginInfo = new ThePluginInfo { DeviceTypes = new List <TheDeviceTypeInfo> { new TheDeviceTypeInfo { Description = "DT1", Capabilities = new eThingCaps[] { eThingCaps.CameraSource, eThingCaps.EnergyMeter }, DeviceType = "TestDeviceType" }, }, }; var pluginInfoClone = pluginInfo.Clone(); Assert.AreNotSame(pluginInfo.DeviceTypes, pluginInfoClone.DeviceTypes); Assert.AreEqual(pluginInfo.DeviceTypes.Count, pluginInfoClone.DeviceTypes.Count); int i = 0; foreach (var dt in pluginInfo.DeviceTypes) { Assert.IsTrue(dt.Description == pluginInfoClone.DeviceTypes[i].Description); Assert.IsTrue(dt.DeviceType == pluginInfoClone.DeviceTypes[i].DeviceType); Assert.AreNotSame(dt.Capabilities, pluginInfoClone.DeviceTypes[i].Capabilities); Assert.AreEqual(dt.Capabilities.Length, pluginInfoClone.DeviceTypes[i].Capabilities.Length); for (int j = 0; j < dt.Capabilities.Length; j++) { Assert.IsTrue(dt.Capabilities[j] == pluginInfoClone.DeviceTypes[i].Capabilities[j]); } } }
private void ShowKPI(int pFldOrder, string pLabel, string pUpdName, int MaxVal = 100, int AveVal = 50, string pUnits = "bytes") { TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.TileGroup, pFldOrder, 0, 0, null, null, new nmiCtrlTileGroup { ParentFld = 300, TileWidth = 6 }); TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.SmartLabel, pFldOrder + 1, 0, 0, null, null, new nmiCtrlSmartLabel { ParentFld = pFldOrder, Text = pLabel, NoTE = true, TileFactorY = 2, TileHeight = 1, TileWidth = 5, ClassName = "cdeTileGroupHeaderSmall" }); var tBut = TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.TileButton, pFldOrder + 2, 2, 0, "V-Tise", null, new nmiCtrlTileButton { ParentFld = pFldOrder, NoTE = true, TileFactorY = 2, TileHeight = 1, TileWidth = 1, ClassName = "cdeGlassButton" }); tBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, $"But{pUpdName}", (sender, para) => { TheThing tT = TheThingRegistry.GetThingByID(MyBaseEngine.GetEngineName(), $"ISO{MyBaseThing.cdeMID}:{pUpdName}"); if (tT == null) { TheKPIReport tRep = new TheKPIReport(null, MyPlugin); TheThing.SetSafePropertyGuid(tRep, "RealSensorThing", MyBaseThing.cdeMID); tRep.GetBaseThing().ID = $"ISO{MyBaseThing.cdeMID}:{pUpdName}"; MyBaseThing.GetProperty(pUpdName, true); TheThing.SetSafePropertyString(tRep, "RealSensorProperty", pUpdName); TheThing.SetSafePropertyNumber(tRep, "StateSensorMaxValue", MaxVal); TheThing.SetSafePropertyNumber(tRep, "StateSensorAverage", AveVal); TheThing.SetSafePropertyNumber(tRep, "StateSensorSteps", MaxVal / 15); TheThing.SetSafePropertyString(tRep, "StateSensorValueName", pLabel); TheThing.SetSafePropertyString(tRep, "StateSensorUnit", pUnits); TheThing.SetSafePropertyString(tRep, "FriendlyName", MyBaseThing.FriendlyName); TheThing.SetSafePropertyString(tRep, "ReportName", $"ISO-KPI: {MyBaseThing.FriendlyName} - {pLabel}"); TheThing.SetSafePropertyString(tRep, "ReportCategory", "ISO KPI Reports"); ThePluginInfo tI = MyPlugin.GetBaseEngine().GetPluginInfo(); if (tI != null) { TheThing.SetSafePropertyString(tRep, "SerialNumber", TheCommonUtils.CStr(tI.CurrentVersion)); TheThing.SetSafePropertyString(tRep, "VendorName", TheCommonUtils.CStr(tI.Developer)); TheThing.SetSafePropertyString(tRep, "ProductName", TheCommonUtils.CStr(tI.ServiceDescription)); TheThing.SetSafePropertyString(tRep, "ProductText", TheCommonUtils.CStr(tI.LongDescription)); TheThing.SetSafePropertyString(tRep, "VendorText", TheCommonUtils.CStr(tI.DeveloperUrl)); TheThing.SetSafePropertyString(tRep, "ProductID", TheCommonUtils.CStr(tI.cdeMID)); } TheThingRegistry.RegisterThing(tRep); MyBaseEngine.ProcessMessage(new TheProcessMessage(new TSM(MyBaseEngine.GetEngineName(), "REFRESH_DASH"))); } else { TheCommCore.PublishToOriginator((para as TheProcessMessage).Message, new TSM(eEngineName.NMIService, "NMI_TTS", tT.cdeMID.ToString())); } }); TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.SmartLabel, pFldOrder + 3, 0, 0, null, pUpdName, new nmiCtrlSingleEnded { ParentFld = pFldOrder, TileWidth = 2 }); TheNMIEngine.AddSmartControl(MyBaseThing, mMyForm, eFieldType.BarChart, pFldOrder + 4, 0, 0, null, pUpdName, new nmiCtrlBarChart() { ParentFld = pFldOrder, MaxValue = MaxVal, TileWidth = 4, NoTE = true, Foreground = "blue" }); }
//Who uses the .CDES File in the store? Moved into platform folder private static void WriteServiceInfo(ThePluginInfo tInfo, string storePath) { string tInfoFile; if (String.IsNullOrEmpty(storePath)) { tInfoFile = TheCommonUtils.cdeFixupFileName($"store\\{tInfo.cdeMID}\\{tInfo.Platform}\\{tInfo.ServiceName}.CDES"); } else { tInfoFile = Path.Combine(storePath, $"{tInfo.ServiceName}.CDES"); } using (StreamWriter sr = new StreamWriter(tInfoFile)) sr.Write(TheCommonUtils.SerializeObjectToJSONString <ThePluginInfo>(tInfo)); }
/// <summary> /// Creates an installation package for a plugin. /// </summary> /// <param name="tInfo">Meta information about the plug-in. (can be null, but then tPlace has to be specified)</param> /// <param name="tPlace">Additional information about the plug-in's presence in a market place (can be null, but then tInfo has to be specified)</param> /// <param name="outputDirectory">Path to a directory that will be used for temporary files as well as the generated installation package</param> /// <param name="bForce">Overwrites output files if they already exists.</param> /// <param name="packageFilePath">Path to the installation package within the outputDirectory.</param> /// <returns>null or empty string if successful. Error information on failure.</returns> public static string CreatePluginPackage(ThePluginInfo tInfo, TheServicesMarketPlace tPlace, string outputDirectory, bool bForce, out string packageFilePath) { packageFilePath = null; string tMetaFile = ""; if (tInfo != null) { if (tInfo.Capabilities != null && tInfo.Capabilities.Contains(eThingCaps.Internal)) { return($"{tInfo.ServiceName} Is Internal Only"); } if (String.IsNullOrEmpty(outputDirectory)) { tMetaFile = TheCommonUtils.cdeFixupFileName($"store\\{tInfo.cdeMID}\\{tInfo.Platform}\\"); } else { tMetaFile = $"{outputDirectory}\\store\\{tInfo.cdeMID}\\{tInfo.Platform}\\"; } if (!Directory.Exists(tMetaFile)) { TheCommonUtils.CreateDirectories(tMetaFile); } WriteServiceInfo(tInfo, outputDirectory); string tgr = tMetaFile + "new\\"; if (TheCommonUtils.IsOnLinux()) { tgr = tgr.Replace('\\', '/'); } if (Directory.Exists(tgr)) { Directory.Delete(tgr, true); } if (tInfo.FilesManifest != null && tInfo.FilesManifest.Count > 0) { foreach (string tFile in tInfo.FilesManifest) { if (tFile == null) { continue; } string tFinalFile = tFile; try { if (tFile.StartsWith("@")) //If a Manifest file starts with @ this function expects this syntax: "@<platform>@<FileName>" { var tC = tFile.Split('@'); if (tC.Length < 3) { continue; } switch (tC[1]) { case "net35": if (tInfo.Platform != cdePlatform.X32_V3) { continue; } break; case "net40": if (tInfo.Platform != cdePlatform.NETV4_32 && tInfo.Platform != cdePlatform.NETV4_64) { continue; } break; case "net45": if (tInfo.Platform != cdePlatform.X64_V3 && tInfo.Platform != cdePlatform.X32_V4) { continue; } break; case "netstandard2.0": break; default: if ((TheCommonUtils.CInt(tC[1]) > 0 && TheCommonUtils.CInt(tC[1]) != TheCommonUtils.CInt(tInfo.Platform))) { continue; } break; } tFinalFile = tC[2]; } string src = TheBaseAssets.MyServiceHostInfo.BaseDirectory; if (TheBaseAssets.MyServiceHostInfo.cdeHostingType == cdeHostType.IIS) { src += "bin\\"; } src += tFinalFile; if (TheCommonUtils.IsOnLinux()) { src = src.Replace('\\', '/'); } tgr = tMetaFile + "new\\" + tFinalFile; if (TheCommonUtils.IsOnLinux()) { tgr = tgr.Replace('\\', '/'); } TheCommonUtils.CreateDirectories(tgr); File.Copy(src, tgr, true); } catch (Exception e) { return(string.Format("Manifest File {0} could not be copied: {1}", tFile, e.ToString())); //TheBaseAssets.MySYSLOG.WriteToLog(2, new TSM("ISMManager", string.Format("Manifest Filer {0} could not be copied.", tFile), eMsgLevel.l1_Error, e.ToString())); //Log Entry that service has been started } } } } else { tMetaFile = TheCommonUtils.cdeFixupFileName(string.Format("store\\{0}\\{1}\\", tPlace.PluginID, tPlace.Platform)); //now PluginID which contains ThePluginInfo.cdeMID } if (tPlace != null && File.Exists(tMetaFile + "META.CDEM")) { TheServicesMarketPlace tPl = null; using (StreamReader sr = new StreamReader(tMetaFile + "META.CDEM")) { String line = sr.ReadToEnd(); tPl = TheCommonUtils.DeserializeJSONStringToObject <TheServicesMarketPlace>(line); } if ((tInfo != null && tInfo.CurrentVersion <= tPl.CurrentVersion) || (tPl != null && tPlace.CurrentVersion <= tPl.CurrentVersion)) { return($"{tPlace?.ServiceName} has existing Version in Store: PInfo:{tInfo?.CurrentVersion} vs Meta:{tPl?.CurrentVersion} vs Place:{tPlace?.CurrentVersion}"); } } if (tPlace == null) { tPlace = new TheServicesMarketPlace(); tPlace.Capabilities = tInfo.Capabilities; tPlace.Categories = tInfo.Categories; tPlace.PluginID = tInfo.cdeMID; //PluginID now contains ThePluginInfo.cdeMID tPlace.CurrentVersion = tInfo.CurrentVersion; tPlace.LongDescription = tInfo.LongDescription; tPlace.Developer = tInfo.Developer; tPlace.DeveloperUrl = tInfo.DeveloperUrl; tPlace.HomeUrl = tInfo.HomeUrl; tPlace.Platform = tInfo.Platform; tPlace.Price = tInfo.Price; tPlace.ServiceName = tInfo.ServiceName; tPlace.AvailableSince = DateTime.Now; tPlace.RaterCount = new List <int>() { 0, 0, 0, 0, 0 }; tPlace.Rating = 0; tPlace.DownloadCounter = 0; tPlace.ServiceDescription = string.IsNullOrEmpty(tInfo.ServiceDescription) ? tInfo.ServiceName : tInfo.ServiceDescription; if (TheBaseAssets.MyServiceHostInfo != null) { if (string.IsNullOrEmpty(tPlace.HomeUrl)) { tPlace.HomeUrl = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false) + "/%PluginID%"; } tPlace.IconUrl = tInfo.IconUrl; if (string.IsNullOrEmpty(tPlace.IconUrl) || tPlace.IconUrl == "toplogo-150.png") { tPlace.IconUrl = "<i class=\"cl-font cl-Logo cl-4x\"></i>"; // TheBaseAssets.MyServiceHostInfo.UPnPIcon; } if (tPlace.IconUrl.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || tPlace.IconUrl.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)) { tPlace.IconUrl = $"<img src='{tPlace.IconUrl}' class='Blocked' width='78' height='78'></img>"; } else if (tPlace.IconUrl.StartsWith("FA")) { tPlace.IconUrl = "<i class='fa faIcon " + (tPlace.IconUrl.Substring(3, 1) == "S" ? "fa-spin " : "") + "fa-" + tPlace.IconUrl.Substring(2, 1) + "x'>&#x" + tPlace.IconUrl.Substring(4, tPlace.IconUrl.Length - 4) + ";</i>"; } } if (Directory.Exists(tMetaFile + "new")) { var res = CreateCDEX(tPlace, tMetaFile, true, out packageFilePath); if (res != null) { return(res); } //Directory.Move(tMetaFile + "new", tMetaFile + "DONE_" + TheCommonUtils.GetTimeStamp()); } else { return("Error: Output directory does not exists"); } } else { if (tInfo.CurrentVersion > tPlace.CurrentVersion) { tPlace.CurrentVersion = tInfo.CurrentVersion; } var res = CreateCDEX(tPlace, tMetaFile, bForce, out packageFilePath); if (res != null) { return(res); } } tPlace.LastUpdate = DateTime.Now; using (StreamWriter sr = new StreamWriter(tMetaFile + "META.CDEM")) sr.Write(TheCommonUtils.SerializeObjectToJSONString <TheServicesMarketPlace>(tPlace)); return(""); }
private static string CreateCDEX(string storeDirectoryPath, ThePluginInfo tInfo, ILogger logger, bool bCheckForFileOverwrite, out string cdexPath) { var pluginTempDirectory = Path.Combine(storeDirectoryPath, $"newCDEX_{Guid.NewGuid()}"); // ensure each plug-in/packging operation gets it's own directory if packaging overlaps for different platforms/flavors of the same plug-in var error = ThePluginPackager.CreatePluginPackage(tInfo, null, pluginTempDirectory, false, out cdexPath); if (string.IsNullOrEmpty(error)) { // Package it into a .CDEP for use with mesh manager string cdepFileName = $"{tInfo.ServiceName.Replace('.', '-')}{(tInfo.Platform > 0 ? $" {tInfo.Platform}" : "")} V{tInfo.CurrentVersion:0.0000}.CDEP"; string cdepFilePath = Path.Combine(storeDirectoryPath, cdepFileName); byte[] oldContent = null; if (File.Exists(cdepFilePath)) { if (bCheckForFileOverwrite) { logger.WriteLine($"WARNING: File conflict: {cdepFilePath} already existed. Replacing."); oldContent = File.ReadAllBytes(cdepFilePath); } File.Delete(cdepFilePath); } else { logger.WriteLine($"Creating file: {cdepFilePath}."); } System.IO.Compression.ZipFile.CreateFromDirectory(Path.Combine(pluginTempDirectory, "store"), cdepFilePath, System.IO.Compression.CompressionLevel.Optimal, false); if (oldContent != null) { var newContent = File.ReadAllBytes(cdepFilePath); if (oldContent.SequenceEqual(newContent)) { logger.WriteLine($"WARNING: Overwritten file was identical: {cdepFilePath}."); } else { logger.WriteLine($"WARNING: Overwritten file was different: {cdepFilePath}."); //File.WriteAllBytes($"{cdepFilePath}.conflict", oldContent); } } } else { logger.WriteLine($"ERROR: {error}"); return(error); } var finalPluginPath = Path.Combine(storeDirectoryPath, Path.GetFileName(cdexPath)); { byte[] oldContent = null; try { if (File.Exists(finalPluginPath)) { if (bCheckForFileOverwrite) { logger.WriteLine($"WARNING: File conflict: {finalPluginPath} already existed."); oldContent = File.ReadAllBytes(finalPluginPath); } File.Delete(finalPluginPath); } else { logger.WriteLine($"Creating file: {finalPluginPath}."); } } catch { } File.Move(cdexPath, finalPluginPath); if (oldContent != null) { var newContent = File.ReadAllBytes(finalPluginPath); if (oldContent.SequenceEqual(newContent)) { logger.WriteLine($"WARNING: Overwritten file was identical: {finalPluginPath}."); } else { logger.WriteLine($"WARNING: Overwritten file was different: {finalPluginPath}."); //File.WriteAllBytes($"{cdepFilePath}.conflict", oldContent); } } } Directory.Delete(pluginTempDirectory, true); cdexPath = finalPluginPath; return(error); }
internal static void InitAssets(TheBaseApplication pApp) { if (IsInitialized) { return; } IsInitialized = true; if (MyServiceHostInfo == null || !(MySecrets?.IsApplicationIDValid() == true)) { MasterSwitch = false; return; } MyApplication = pApp; #region step 1: Moved from StartApplication to here as all the following code is updating TheBaseAssets //The following section are "app.config" only settings required before cdeTPI is loaded. These settings cannot be set via the Provisioning Service int delay = TheCommonUtils.CInt(MySettings.GetSetting("StartupDelay")); if (delay > 0) { TheCommonUtils.SleepOneEye((uint)(delay * 1000), 100); } string temp = MySettings.GetSetting("AllowEnvironmentVarsToOverrideConfig"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.AllowEnvironmentVarsToOverrideConfig = TheCommonUtils.CBool(temp); } temp = MySettings.GetSetting("AllowEnvironmentVars"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.AllowEnvironmentVars = TheCommonUtils.CBool(temp); } temp = MySettings.GetSetting("DEBUGLEVEL"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.DebugLevel = (eDEBUG_LEVELS)TheCommonUtils.CInt(temp); } //Clouds have special behavior and the CDE needs to know this upfront temp = MySettings.GetSetting("IsCloudService"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.IsCloudService = TheCommonUtils.CBool(temp); } temp = MySettings.GetSetting("ISOEN"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.IsIsolated = true; MyServiceHostInfo.IsoEngine = temp; MyServiceHostInfo.cdeNodeType = cdeNodeType.Active; } else { temp = MySettings.GetSetting("UseRandomDeviceID"); if (!string.IsNullOrEmpty(temp)) { MyServiceHostInfo.UseRandomDeviceID = TheCommonUtils.CBool(temp); } } //Step 2: Restore from backup if exists #if CDE_NET45 // Backup/Restore only support on NET45 // To ensure that restored backups are not overwritten during shutdown, we write them to a temp directory and move them into place on start up if (!MyServiceHostInfo.UseRandomDeviceID && !MyServiceHostInfo.IsIsolated) { string cacheParentPath = TheCommonUtils.GetCurrentAppDomainBaseDirWithTrailingSlash() + "ClientBin\\"; if (Directory.Exists(cacheParentPath + "__CacheToRestore")) { // Keep the old Cache around just in case try { // First make space for the old copy, in case there was one already if (Directory.Exists(cacheParentPath + "__CacheOld")) { Directory.Delete(cacheParentPath + "__CacheOld", true); } } catch { //ignored } try { Directory.Move(cacheParentPath + "Cache", cacheParentPath + "__CacheOld"); } catch { //ignored } // Now move the restored cache into place try { Directory.Move(cacheParentPath + "__CacheToRestore", cacheParentPath + "Cache"); } catch { TheSystemMessageLog.ToCo("Failure while restoring backup"); } } } #endif MyServiceHostInfo.EnableTaskKPIs = TheCommonUtils.CBool(MySettings.GetSetting("EnableTaskKPIs")); if (MyServiceHostInfo.EnableTaskKPIs) { var taskKpiThread = new Thread(() => { do { var kpis = TheCommonUtils.GetTaskKpis(null); TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: {TheCommonUtils.SerializeObjectToJSONString(kpis)}"); Thread.Sleep(1000); // Keeping it simple here, to minimize interference on task scheduler/thread scheduler etc. (Assumption: not used on production systems) // TheCommonUtils.SleepOneEye(1000, 1000); } while (MasterSwitch && !Engines.TheCDEngines.IsHostReady && MyServiceHostInfo.EnableTaskKPIs); TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: KPIs Handoff to NodeHost"); }); taskKpiThread.Start(); } #endregion if (MyActivationManager == null) { MyActivationManager = new TheDefaultActivationManager(MySecrets, MySYSLOG); } #region step 3: analyse os environment information OperatingSystem os = Environment.OSVersion; var osInfoForLog = $"C-DEngine version: {BuildVersion} OS:{Environment.OSVersion} OS Version:{os.VersionString} OS Version Numbers: {os.Version.Major}.{os.Version.Minor}.{os.Version.Build}.{os.Version.Revision} Platform:{os.Platform} SP:{os.ServicePack} Processor Count: {Environment.ProcessorCount} IsMono:{(Type.GetType("Mono.Runtime") != null)} IsNetCore:{TheCommonUtils.IsNetCore()} Product: {TheCommonUtils.GetAssemblyProduct(typeof(TheBaseAssets))} "; TheSystemMessageLog.ToCo(osInfoForLog); MyServiceHostInfo.OSInfo = osInfoForLog; string dotNetInfoForLog = string.Empty; #if !CDE_NET35 && !CDE_NET4 try { string frameworkDescription = null; string osDescription = null; string processArchitecture = null; string osArchitecture = null; #if CDE_STANDARD frameworkDescription = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription; osDescription = System.Runtime.InteropServices.RuntimeInformation.OSDescription; processArchitecture = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString(); osArchitecture = System.Runtime.InteropServices.RuntimeInformation.OSArchitecture.ToString(); #else var rtInfoType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); if (rtInfoType != null) { frameworkDescription = rtInfoType.GetProperty("FrameworkDescription").GetValue(null).ToString(); osDescription = rtInfoType.GetProperty("OSDescription").GetValue(null).ToString(); processArchitecture = rtInfoType.GetProperty("ProcessArchitecture").GetValue(null).ToString(); osArchitecture = rtInfoType.GetProperty("OSArchitecture").GetValue(null).ToString(); } #endif if (!string.IsNullOrEmpty(frameworkDescription)) { dotNetInfoForLog = $"NetFrameWork:{frameworkDescription} Processor:{processArchitecture} OS:{osDescription } OS Arch:{osArchitecture}"; TheSystemMessageLog.ToCo(dotNetInfoForLog); MyServiceHostInfo.OSInfo += $" {dotNetInfoForLog}"; } } catch { } #endif if (TheCommonUtils.IsMono()) // CODE REVIEW: Need to clean this up - do we mean Mono or Linux or case-insensitive file systems? CM: No- here we need this to find out if we are running in the MONO Runtime { MyServiceHostInfo.cdePlatform = cdePlatform.MONO_V3; } else { #if CDE_NET35 MyServiceHostInfo.cdePlatform = cdePlatform.X32_V3; #elif CDE_NET4 MyServiceHostInfo.cdePlatform = Environment.Is64BitProcess ? cdePlatform.NETV4_64 : cdePlatform.NETV4_32; #elif CDE_STANDARD MyServiceHostInfo.cdePlatform = cdePlatform.NETSTD_V20; #else MyServiceHostInfo.cdePlatform = TheCommonUtils.GetAssemblyPlatform(Assembly.GetEntryAssembly(), false, out var empty);// old: Environment.Is64BitProcess ? cdePlatform.X64_V3 : cdePlatform.X32_V4; #endif } TheSystemMessageLog.ToCo("BaseDir: " + MyServiceHostInfo.BaseDirectory); #endregion #region step 4: Prepare essential Subsystems (Syslog, ScopeManager, Diagnostics, Caches, AppInfo) MySYSLOG = new TheSystemMessageLog(500); // No more ToCo after this point (will be ignored) TheCDEKPIs.Reset(); MyServiceHostInfo.MiniHostInfo.MySYSLOG = MySYSLOG; MyServiceHostInfo.MiniHostInfo.MyKPIs = new TheKPIs(); if (MyScopeManager == null) { MyScopeManager = new TheDefaultScopeManager(); } MyScopeManager.SetMiniHSI(MyServiceHostInfo.MiniHostInfo); MyScopeManager.RegisterScopeChanged(localEventScopeChanged); TheDiagnostics.InitDiagnostics(); TheDiagnostics.SetThreadName("MAIN THREAD"); TheQueuedSenderRegistry.Startup(); MyBlobCache = new TheMirrorCache <TheBlobData>(MyServiceHostInfo.TO.StorageCleanCycle); MyReceivedParts = new TheMirrorCache <TheReceivedParts>(MyServiceHostInfo.TO.StorageCleanCycle); //TODO: I hope there is a better way to do this for Metro! MyServiceTypes.Add(typeof(TheBaseAssets)); MyServiceHostInfo.TO.MakeHeartNormal(); MyAppInfo = new ThePluginInfo { cdeMID = MyServiceHostInfo.cdeMID, CurrentVersion = MyServiceHostInfo.CurrentVersion, Developer = MyServiceHostInfo.VendorName, DeveloperUrl = MyServiceHostInfo.VendorUrl, HomeUrl = MyServiceHostInfo.SiteName, IconUrl = MyServiceHostInfo.UPnPIcon, LongDescription = MyServiceHostInfo.Description, Platform = MyServiceHostInfo.cdePlatform, Copyrights = MyServiceHostInfo.Copyrights, Price = 0, ServiceDescription = MyServiceHostInfo.Title, ServiceName = MyServiceHostInfo.ApplicationName, Capabilities = new List <eThingCaps> { eThingCaps.Host }, Categories = new List <string>(), FilesManifest = new List <string>() }; if (MyServiceHostInfo.ManifestFiles != null) { MyAppInfo.FilesManifest.AddRange(MyServiceHostInfo.ManifestFiles); } #endregion //Now load provisioning and local settings then parse them #pragma warning disable CS0618 // Type or member is obsolete - its allowed here if (!TheCDESettings.ParseSettings(MyCmdArgs, true, false)) #pragma warning restore CS0618 // Type or member is obsolete { MasterSwitch = false; return; } if (MyCodeSigner == null) { MyCodeSigner = new TheDefaultCodeSigning(MySecrets, MySYSLOG); } string tBaseDir = MyServiceHostInfo.BaseDirectory; if (MyServiceHostInfo.cdeHostingType == cdeHostType.IIS) { tBaseDir += "bin\\"; } string uDir = tBaseDir; if (!string.IsNullOrEmpty(MyServiceHostInfo.ISMMainExecutable)) { uDir += MyServiceHostInfo.ISMMainExecutable; if (MyServiceHostInfo.cdeHostingType != cdeHostType.IIS) { var hostPath = uDir + ".exe"; if (!File.Exists(hostPath)) { // We may be running under .Net Core with a .dll-based host hostPath = uDir + ".dll"; } uDir = hostPath; } } else { uDir += "C-DEngine.dll"; } MyServiceHostInfo.CodeSignThumb = MyCodeSigner.GetAppCert(MyServiceHostInfo.DontVerifyTrust, uDir, MyServiceHostInfo.VerifyTrustPath, MyServiceHostInfo.DontVerifyIntegrity); //Must be loaded here to set trust level in HSI if (MyLoc as TheDefaultLocalizationUtils != null) { (MyLoc as TheDefaultLocalizationUtils).DoPseudoLoc = TheCommonUtils.CBool(MySettings.GetSetting("DoPseudoLoc")); } #region step 5: output some system information if (MyServiceHostInfo.IsMemoryOptimized) { MySYSLOG.SetMaxLogEntries(10); } MySYSLOG.WriteToLog(4151, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", osInfoForLog, eMsgLevel.l4_Message)); if (!string.IsNullOrEmpty(dotNetInfoForLog)) { MySYSLOG.WriteToLog(4152, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", dotNetInfoForLog, eMsgLevel.l4_Message)); } MySYSLOG.WriteToLog(4153, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("TheBaseAssets", "BaseDir: " + MyServiceHostInfo.BaseDirectory, eMsgLevel.l4_Message)); #endregion #region step 6: determine WebSocket8 vs. WebSocketsSharp var ws8FlagTemp = MySettings.GetSetting("DisallowWebSocket8"); if (!string.IsNullOrEmpty(ws8FlagTemp)) { MyServiceHostInfo.IsWebSocket8Active = !TheCommonUtils.CBool(ws8FlagTemp); MySYSLOG.WriteToLog(4154, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", $"Setting IsWebSocket8Active to {MyServiceHostInfo.IsWebSocket8Active} due to config", eMsgLevel.l4_Message)); } else { MyServiceHostInfo.IsWebSocket8Active = true; } if ((os.Platform != PlatformID.Win32NT && !TheCommonUtils.IsNetCore()) || (os.Platform == PlatformID.Win32NT && (os.Version.Major < 6 || (os.Version.Major == 6 && os.Version.Minor < 2)))) { MyServiceHostInfo.IsWebSocket8Active = false; string tWSMsg = "Older Windows or non-Windows OS Detected - No OS Support for WebSockets Found: "; #if !CDE_USECSWS //OK TheBaseAssets.MyServiceHostInfo.DisableWebSockets = true; tWSMsg += "WebSockets are turned Off"; #else tWSMsg += "Switching to WebSockets-Sharp"; #endif MySYSLOG.WriteToLog(4155, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", tWSMsg, eMsgLevel.l4_Message)); } #endregion #region step 7: Initialize Localization subsystem (ILocalizationHooks) bool bLocInitialized = false; try { var entryAssembly = Assembly.GetEntryAssembly(); //This does not work in IIS! if (entryAssembly != null) { var CDEPlugins = from t in entryAssembly.GetTypes() let ifs = t.GetInterfaces() where ifs != null && ifs.Length > 0 && (ifs.Contains(typeof(ILocalizationHooks))) select new { Type = t, t.Namespace, t.Name, t.FullName }; if (CDEPlugins != null && CDEPlugins.Any()) { MyLoc = Activator.CreateInstance(CDEPlugins.First().Type) as ILocalizationHooks; } bLocInitialized = true; } } catch { } if (!bLocInitialized) { MySYSLOG.WriteToLog(4156, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", "3rd Party ILocalization Hooks not found - using built-in", eMsgLevel.l4_Message)); } #endregion #region step 8: Set MyStationUrl switch (MyServiceHostInfo.cdeHostingType) { case cdeHostType.Phone: case cdeHostType.Metro: MyServiceHostInfo.MyDeviceMoniker = "CDEV://"; break; case cdeHostType.Silverlight: MyServiceHostInfo.MyDeviceMoniker = "CDES://"; break; case cdeHostType.Device: MyServiceHostInfo.MyDeviceMoniker = "CDEC://"; break; case cdeHostType.Mini: MyServiceHostInfo.MyDeviceMoniker = "CDEM://"; break; default: //Services MyServiceHostInfo.MyDeviceMoniker = "CDEB://"; break; } if (TheCommonUtils.IsHostADevice()) { MyServiceHostInfo.MyStationURL = MyServiceHostInfo.MyDeviceMoniker + "{" + MyServiceHostInfo.MyDeviceInfo.DeviceID + "}".ToUpper(); //MSU-OK } else { if (MyServiceHostInfo.MyAltStationURLs.Count(s => s.StartsWith("CDEB")) == 0) { MyServiceHostInfo.MyAltStationURLs.Add("CDEB://{" + MyServiceHostInfo.MyDeviceInfo.DeviceID + "}"); //TODO: Backchannel Possibly save to Config File } } #endregion #region step 9: Start Localhost QSender and SessionStateManager MySession = new TheSessionStateManager(MyServiceHostInfo); LocalHostQSender = new TheQueuedSender(); //NO connected or Error Event necessary LocalHostQSender.StartSender(new TheChannelInfo(MyServiceHostInfo.MyDeviceInfo.DeviceID, MyScopeManager.ScopeID, MyServiceHostInfo.MyDeviceInfo.SenderType, MyServiceHostInfo.GetPrimaryStationURL(false)), null, false); //NEW:2.06 Setting Realscope here ///null correct - no subs on LocalhostQS in beginning //RScope-OK if ((MyServiceHostInfo.DisableWebSockets || MyServiceHostInfo.MyStationWSPort == 0) && !TheCommonUtils.IsHostADevice()) { MySYSLOG.WriteToLog(4157, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", $"WebSockets Disabled - no WSPort specified {MyServiceHostInfo.MyStationWSPort} or DisableWebSocket={MyServiceHostInfo.DisableWebSockets}", eMsgLevel.l4_Message)); } #endregion // Post Device ID settings //Step 10: Save all settings to local cdeTPI MySettings.UpdateLocalSettings(); }