public void AddSlot(ServiceStarterElement eleConfig, Process p, string signal) { ServiceSlot slot = new ServiceSlot() { Name = eleConfig.Name, Config = eleConfig, WorkProcess = p, Signal = signal }; _Slots.Add(slot); }
public ActionResult StartService(string name) { ActionResult retValue = new ActionResult() { Result = -1 }; if (1 == _StartLockCount) { retValue.Message = "正在启动一个服务,请稍后再试"; return(retValue); } Interlocked.Increment(ref _StartLockCount); "尝试启动服务:{0}".Formate(name).Info(); ServiceSlot slot = ServiceContext.Current.ServiceSlots.FirstOrDefault(s => s.Name == name); ServiceStarterElement ele = ServiceContext.Current.Configuration.Services.Cast <ServiceStarterElement>().FirstOrDefault(s => s.Name == name); if (null != slot) { Interlocked.Decrement(ref _StartLockCount); retValue.Message = "服务:{0} 已经启动".Formate(name); retValue.Message.Info(); } else { string msg = ""; if (null != ele) { if (!BasicServiceStarter.RunServiceProcess(ServiceContext.Current.Configuration.ServiceInfo.Name, ele, out msg)) { retValue.Message = msg; msg.Error(); } else { retValue.Result = 0; } } else { retValue.Message = "找不到服务:{0} 的配置".Formate(name);; } Interlocked.Decrement(ref _StartLockCount); } return(retValue); }
public static bool RunServiceProcess(string domain, ServiceStarterElement eleConfig, out string msg) { bool retValue = false; string signal = Guid.NewGuid().ToString(); msg = ""; try { string contentFullPath = eleConfig.ContentPath; if (!Path.IsPathRooted(contentFullPath)) { contentFullPath = Path.Combine(Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory.TrimEnd(new char[] { '\\' })).FullName, "services", contentFullPath.TrimStart(new char[] { '~' }).TrimStart(new char[] { '/' })); } Process p = new Process(); p.StartInfo.Arguments = string.Format(" -n={0} -g={1} -c=\"{2}\" -a={3} -t={4} -m={5} -d={6}", eleConfig.Name, signal, contentFullPath, eleConfig.AssemblyName, eleConfig.TypeName, domain, ServiceContext.Current.IsDebug ? "Y" : "N"); p.StartInfo.CreateNoWindow = true; p.StartInfo.FileName = "cstarter.exe"; p.StartInfo.UseShellExecute = false; p.StartInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived); p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived); p.Start(); p.BeginErrorReadLine(); p.BeginOutputReadLine(); CancellationTokenSource token = new CancellationTokenSource(); Task t = new Task(() => { while (!token.IsCancellationRequested) { if (p.HasExited) { "服务进程 {0} 已经退出 {1}".Formate(eleConfig.Name, p.ExitCode.ToString()).Error(); ServiceContext.Current.ServiceStartedComplete(); break; } } }, token.Token); string.Format("等待服务 {0} 启动完成", eleConfig.Name).Info(); t.Start(); if (ServiceContext.Current.WaitServiceStarting(30)) { token.Cancel(); if (!p.HasExited) { "服务{0}已经成功启动".Formate(eleConfig.Name).Info(); ServiceContext.Current.AddSlot(eleConfig, p, signal); retValue = true; } else { switch (p.ExitCode) { case 0: "程序已退出,但是未返回错误码".Error(); break; case -1: "必须指定一个服务名称".Error(); break; case -2: "必须给定服务域".Error(); break; case -3: "必须指定一个信号量".Error(); break; case -4: "必须指定运行的路径".Error(); break; case -5: "运行路径必须是绝对路径".Error(); break; case -6: "必须指定入口类库".Error(); break; case -7: "必须指定入口类".Error(); break; case -100: "服务进程启动过程中发生错误,请查看服务进程启动日志获取详细信息".Error(); break; default: ("启动发生未知错误:" + p.ExitCode.ToString()).Error(); break; } } } else { token.Cancel(); "在限定的时间内,启动的服务无响应,服务{0}可能没有成功启动".Formate(eleConfig.Name).Warn(); ServiceContext.Current.AddSlot(eleConfig, p, signal); retValue = true; } } catch (Exception eX) { msg = eX.Message; eX.Exception(); } return(retValue); }