/// <summary> /// start service host by serviceInfo /// </summary> /// <param name="serviceInfo"></param> /// <returns></returns> public static int OpenService(ServiceInfo serviceInfo) { void SetEnvironment() { if (serviceInfo.Environment == null) { TraceHelper.TraceVerbose(Utility.GetJobId(), "No environment fond."); return; } foreach (var env in serviceInfo.Environment) { Environment.SetEnvironmentVariable(env.Key, env.Value); TraceHelper.TraceVerbose(Utility.GetJobId(), $"Set environment {env.Key}={env.Value}."); } } async Task <string[]> DownloadDependFiles() { if (serviceInfo.DependFiles != null && serviceInfo.DependFiles.Any()) { var downloadTasks = serviceInfo.DependFiles.Select(fileInfo => StandaloneDataClient.DownloadFileFromSasAsync( fileInfo.Value, Path.Combine(Path.Combine(Path.GetTempPath(), "ExcelOffloading"), Path.GetFileName(fileInfo.Key)))); return(await Task.WhenAll(downloadTasks)); } else { TraceHelper.TraceVerbose(Utility.GetJobId(), "No depend files fond."); return(new string[0]); } } Environment.SetEnvironmentVariable(Constant.JobIDEnvVar, serviceInfo.JobId.ToString()); Environment.SetEnvironmentVariable(Constant.TaskIDEnvVar, serviceInfo.TaskId.ToString()); Environment.SetEnvironmentVariable(Constant.CoreIdsEnvVar, serviceInfo.CoreId.ToString()); Environment.SetEnvironmentVariable(Constant.ServiceConfigFileNameEnvVar, serviceInfo.FileName); if (!string.IsNullOrEmpty(serviceInfo.RegistrationPath)) { Environment.SetEnvironmentVariable(Constant.RegistryPathEnv, serviceInfo.RegistrationPath); } else { Environment.SetEnvironmentVariable(Constant.RegistryPathEnv, Path.Combine(Environment.CurrentDirectory, defaultRegistryPath)); } TraceHelper.TraceVerbose(Utility.GetJobId(), $"Set {Constant.RegistryPathEnv} to {Environment.GetEnvironmentVariable(Constant.RegistryPathEnv)}"); // use default values for following environment variables Environment.SetEnvironmentVariable(Constant.ProcNumEnvVar, "1"); Environment.SetEnvironmentVariable(Constant.NetworkPrefixEnv, Constant.EnterpriseNetwork); Environment.SetEnvironmentVariable(Constant.ServiceInitializationTimeoutEnvVar, "60000"); Environment.SetEnvironmentVariable(Constant.CancelTaskGracePeriodEnvVar, "15"); Environment.SetEnvironmentVariable(Constant.ServiceConfigMaxMessageEnvVar, "65536"); Environment.SetEnvironmentVariable(Constant.ServiceConfigServiceOperatonTimeoutEnvVar, "86400000"); // the local host process won't be preempted by the scheduler Environment.SetEnvironmentVariable(Constant.EnableMessageLevelPreemptionEnvVar, bool.FalseString); SetEnvironment(); var dependFilePath = DownloadDependFiles().GetAwaiter().GetResult(); Environment.SetEnvironmentVariable(Constant.DataServiceSharedFileEnvVar, string.Join(";", dependFilePath)); #if DEBUG #region For EndpointNotFoundException test try { string strWaitPeriod = ConfigurationManager.AppSettings["Test_WaitPeriodBeforeStartup"]; if (!string.IsNullOrEmpty(strWaitPeriod)) { int waitPeriodInMilliSecond = int.Parse(strWaitPeriod); Console.Error.WriteLine("Debug: waiting {0} ms before startup service", waitPeriodInMilliSecond); Thread.Sleep(waitPeriodInMilliSecond); } } catch (Exception) { // do nothing } #endregion #endif jobId = Utility.GetJobId(); string serviceConfigFullPath; bool onAzure = SoaHelper.IsOnAzure(); TraceHelper.TraceInfo( jobId, "OnAzure = {0}", onAzure); bool bOpenDummy = false; try { string serviceConfigFileName = Environment.GetEnvironmentVariable(Constant.ServiceConfigFileNameEnvVar); // exit if no such env var if (string.IsNullOrEmpty(serviceConfigFileName)) { bOpenDummy = true; Console.Error.WriteLine(StringTable.ServiceConfigFileNameNotSpecified); return(ErrorCode.ServiceHost_ServiceConfigFileNameNotSpecified); } if (onAzure) { string localCacheFolder = Utility.GetServiceLocalCacheFullPath(); serviceConfigFullPath = Path.Combine(localCacheFolder, serviceConfigFileName); } else { serviceConfigFullPath = GetServiceInfo(serviceConfigFileName); } if (!File.Exists(serviceConfigFullPath)) { bOpenDummy = true; Console.Error.WriteLine(StringTable.CantFindServiceRegistrationFile, serviceConfigFullPath); return(ErrorCode.ServiceHost_ServiceRegistrationFileNotFound); } TraceHelper.TraceInfo( jobId, "ServiceConfigFullPath = {0}", serviceConfigFullPath); ServiceRegistration registration; string assemblyFullPath; int errorCode = Utility.GetServiceRegistration(serviceConfigFullPath, onAzure, out registration, out assemblyFullPath); if (errorCode != ErrorCode.Success) { bOpenDummy = true; return(errorCode); } // Open the host in another application domain AppDomain domain = CreateNewServiceDomain(serviceConfigFullPath, assemblyFullPath); using (CcpServiceHostWrapper host = CreateInstanceFromAndUnwrap <CcpServiceHostWrapper>( domain, Assembly.GetExecutingAssembly().Location, serviceConfigFullPath, onAzure, ServiceHostRuntimeConfiguration.Standalone)) { host.Initialize(); host.Run(); TraceHelper.TraceInfo( jobId, "Sleep..."); if (ServiceHostRuntimeConfiguration.Standalone) { // Endless listening, till service info deleted. while (true) { lock (ServiceInfo.s_lock) { if (SvcHostMgmtRestServer.Info == null) { TraceHelper.TraceInfo( jobId, "Close service host!"); host.Dispose(); return(0); } } Thread.Sleep(1000); } } else { // Endless waiting, till it's being killed Thread.Sleep(Timeout.Infinite); } } } catch (Exception e) { Console.Error.WriteLine(e.Message); TraceHelper.TraceError( jobId, e.ToString()); // Failed to open service, fall back to open an dummy service. bOpenDummy = true; } finally { if (bOpenDummy) { OpenDummyService(onAzure); } } return(0); }