示例#1
0
        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);
        }