/** * 采用nssm来第一次安装服务 */ public static bool NssmInstallAndStart(string serviceName, string param, string execFullPath, string serviceStartType, string serviceDescription, Action <string> log) { string nssmPath = Path.Combine(Startup.RootPath, "nssm.exe"); if (!File.Exists(nssmPath)) { throw new FileNotFoundException(nssmPath); } log($"nssm.exe install {serviceName} \"{execFullPath}\""); var rt = ProcessHepler.RunExternalExe(nssmPath, $"install {serviceName} \"{execFullPath}\"", log); if (!rt) { return(false); } log($"nssm.exe set {serviceName} AppDirectory \"{new FileInfo(execFullPath).DirectoryName}\""); rt = ProcessHepler.RunExternalExe(nssmPath, $"set {serviceName} AppDirectory \"{new FileInfo(execFullPath).DirectoryName}\"", log); if (!rt) { return(false); } if (!string.IsNullOrEmpty(serviceDescription)) { log($"nssm.exe set {serviceName} Description \"{serviceDescription}\""); rt = ProcessHepler.RunExternalExe(nssmPath, $"set {serviceName} Description \"{serviceDescription}\"", log); if (!rt) { return(false); } } if (!string.IsNullOrEmpty(param)) { log($"nssm.exe set {serviceName} AppParameters \"{param}\""); rt = ProcessHepler.RunExternalExe(nssmPath, $"set {serviceName} AppParameters \"{param}\"", log); if (!rt) { return(false); } } if (!string.IsNullOrEmpty(serviceStartType) && !serviceStartType.ToLower().Equals("auto")) { log($"nssm.exe set {serviceName} Start SERVICE_DEMAND_START"); rt = ProcessHepler.RunExternalExe(nssmPath, $"set {serviceName} Start SERVICE_DEMAND_START", log); if (!rt) { return(false); } } ServiceInstaller.StartService(serviceName); return(true); }
private void killPool() { //执行终极方法 执行pool的回收 因为每个应用的pool是唯一的情况下 不会影响别的站点 var r1 = ProcessHepler.RunAppCmd($"recycle apppool /apppool.name:\"{this.args.ApplicationPoolName}\"", logger); logger($"recycle apppool /apppool.name:{this.args.ApplicationPoolName} ===> {(r1 ? "Success" : "Fail")}"); var r2 = ProcessHepler.RunAppCmd($"stop apppool /apppool.name:\"{this.args.ApplicationPoolName}\"", logger); logger($"stop apppool /apppool.name:{this.args.ApplicationPoolName} ===> {(r2 ? "Success" : "Fail")}"); // 直接关闭站点可能会影响其他的站点 //var r3 = ProcessHepler.RunAppCmd($"stop site /site.name:\"{this.args.SiteName}\"", logger); //logger($"stop site /site.name:{this.args.SiteName} ===> {(r3 ? "Success" : "Fail")}"); }
public override void Deploy() { try { base.Deploy(); } catch (Exception exception) { logger("Copy File Fail :" + exception.Message); retryTimes++; logger("Wait 5Seconds to Retry :" + retryTimes); Thread.Sleep(5000); if (retryTimes > 3) { //执行终极方法 用sc命令执行 var r1 = ProcessHepler.RuSCCmd($"stop \"{this.args.AppName}\"", logger); logger($"sc stop {this.args.AppName} ===> {(r1 ? "Success" : "Fail")}"); logger("Wait 5Seconds to Try deploy again"); Thread.Sleep(5000); try { base.Deploy(); return; } catch (Exception) { try { logger("Wait 5Seconds to Try deploy again+1"); Thread.Sleep(5000); base.Deploy(); return; } catch (Exception) { logger("【Error】Retry Copy Limit "); throw; } } } Deploy(); } }
public override void Deploy() { try { base.Deploy(); } catch (Exception exception) { logger("Copy File Fail :" + exception.Message); retryTimes++; logger("Wait 5Senconds to Retry :" + retryTimes); Thread.Sleep(5000); if (retryTimes > 3) { //执行终极方法 var r1 = ProcessHepler.RunAppCmd($"recycle apppool /apppool.name:\"{this.args.ApplicationPoolName}\"", logger); logger($"recycle apppool /apppool.name:{this.args.ApplicationPoolName} ===> {(r1 ? "Success" : "Fail")}"); var r2 = ProcessHepler.RunAppCmd($"stop apppool /apppool.name:\"{this.args.ApplicationPoolName}\"", logger); logger($"stop apppool /apppool.name:{this.args.ApplicationPoolName} ===> {(r2 ? "Success" : "Fail")}"); var r3 = ProcessHepler.RunAppCmd($"stop site /site.name:\"{this.args.SiteName}\"", logger); logger($"stop site /site.name:{this.args.SiteName} ===> {(r3 ? "Success" : "Fail")}"); logger("Wait 5Senconds to Try deploy again"); Thread.Sleep(5000); try { base.Deploy(); return; } catch (Exception) { logger("【Error】Retry Copy Limit "); throw; } } Deploy(); } }
public override void Deploy() { try { if (args.UseOfflineHtm) { try { var createErr = IISHelper.CreateAppOffineHtm(this.args.AppFolder); if (!string.IsNullOrEmpty(createErr)) { logger($"【Error】Create app_offline.htm to [{this.args.AppFolder}] Fail:[{createErr}]"); return; } logger($"create app_offline.htm to [{this.args.AppFolder}] Success"); //创建了app_offline.htm成功后 iis会解除占用 //执行copy base.Deploy(); } finally { var deleteErr = IISHelper.DeleteAppOfflineHtm(this.args.AppFolder); if (!string.IsNullOrEmpty(deleteErr)) { logger($"【Error】delete app_offline.htm from [{this.args.AppFolder}] Fail:[{deleteErr}]"); } logger($"delete app_offline.htm from [{this.args.AppFolder}] Success"); } } else { base.Deploy(); } } catch (Exception exception) { logger("Copy File Fail :" + exception.Message); retryTimes++; logger("Wait 5Senconds to Retry :" + retryTimes); Thread.Sleep(5000); if (retryTimes > 3) { //执行终极方法 var r1 = ProcessHepler.RunAppCmd($"recycle apppool /apppool.name:\"{this.args.ApplicationPoolName}\"", logger); logger($"recycle apppool /apppool.name:{this.args.ApplicationPoolName} ===> {(r1 ? "Success" : "Fail")}"); var r2 = ProcessHepler.RunAppCmd($"stop apppool /apppool.name:\"{this.args.ApplicationPoolName}\"", logger); logger($"stop apppool /apppool.name:{this.args.ApplicationPoolName} ===> {(r2 ? "Success" : "Fail")}"); var r3 = ProcessHepler.RunAppCmd($"stop site /site.name:\"{this.args.SiteName}\"", logger); logger($"stop site /site.name:{this.args.SiteName} ===> {(r3 ? "Success" : "Fail")}"); logger("Wait 5Senconds to Try deploy again"); Thread.Sleep(5000); try { base.Deploy(); return; } catch (Exception) { logger("【Error】Retry Copy Limit "); throw; } } Deploy(); } }
public override string RollBack() { try { var projectPath = Path.Combine(Setting.PublishWindowServicePathFolder, _serviceName); _projectPublishFolder = Path.Combine(projectPath, _dateTimeFolderName); if (!Directory.Exists(_projectPublishFolder)) { return("rollback folder not found:" + _projectPublishFolder); } #if NETCORE Log("netcore agent version ==>" + Version.VERSION); #else Log("netframework agent version ==>" + Version.VERSION); #endif var deployFolder = findUploadFolder(_projectPublishFolder); var incrementFolder = Path.Combine(_projectPublishFolder, "increment"); if (Directory.Exists(incrementFolder)) { deployFolder = incrementFolder; } if (!Directory.Exists(deployFolder)) { return("rollback folder not found:" + deployFolder); } Log("rollback from folder ==>" + deployFolder); var service = WindowServiceHelper.GetWindowServiceByName(this._serviceName); if (!string.IsNullOrEmpty(service.Item2)) { return(service.Item2); } if (service.Item1 == null) { return("service not found:" + _serviceName); } var projectLocation = WindowServiceHelper.GetWindowServiceLocation(this._serviceName); if (string.IsNullOrEmpty(projectLocation)) { return($"can not find executable path of service:{_serviceName}"); } //处理使用 nssm 安装的 Windows 服务程序 if (projectLocation.EndsWith("nssm.exe", true, CultureInfo.CurrentCulture)) { Log("service is installed by NSSM process."); var _nssmOutput = ""; ProcessHepler.RunExternalExe(projectLocation, $"get {_serviceName} Application", output => { _nssmOutput += Regex.Replace(output, @"\0", ""); }); if (string.IsNullOrEmpty(_nssmOutput.Trim())) { return($"can not find real executable path of nssm service:{_serviceName}"); } projectLocation = _nssmOutput; } var projectLocationFolder = string.Empty; try { projectLocation = projectLocation.Replace("\"", ""); projectLocationFolder = new FileInfo(projectLocation).DirectoryName; if (!Directory.Exists(projectLocationFolder)) { //如果目录不存在 那么就重新建立 return($"can not find executable path of service:{_serviceName}"); } } catch (Exception) { return("ServiceFolder is not correct ===> " + projectLocationFolder); } Log("Start to rollback Windows Service:"); Log("ServiceName ===>" + _serviceName); Log("ServiceFolder ===> " + projectLocationFolder); Arguments args = new Arguments { DeployType = "WindowsService", BackupFolder = Setting.BackUpWindowServicePathFolder, AppName = _serviceName, AppFolder = projectLocationFolder, DeployFolder = deployFolder, WaitForWindowsServiceStopTimeOut = _waitForServiceStopTimeOut, NoBackup = true, }; var ops = new OperationsWINDOWSSERVICE(args, Log); try { ops.Execute(); SaveCurrentVersion(new DirectoryInfo(deployFolder).Parent.FullName); Log("Rollback WindowsService Execute Success"); } catch (Exception ex) { try { return($"Rollback to WindowsService err:{ex.Message}"); } catch (Exception ex2) { return($"Rollback to WindowsService err:{ex.Message}, fail:{ex2.Message}"); } } return(string.Empty); } catch (Exception ex1) { return(ex1.Message); } finally { cleanRollbackTemp(); } }
public override void Deploy() { if (args.UseTempPhysicalPath) { //先从iis站点 this.args.AppFolder 复制 到 当前 日期文件夹下的deploy文件夹 然后在 DeployFolder 复制到 日期文件夹下的deploy文件夹 var isSuccess = CopyHelper.ProcessXcopy(this.args.AppFolder, this.args.TempPhysicalPath, logger); if (!isSuccess) { logger($"【Error】Copy `{this.args.AppFolder}` to `{this.args.TempPhysicalPath}` fail"); throw new Exception($"Copy `{this.args.AppFolder}` to `{this.args.TempPhysicalPath}` fail"); } isSuccess = CopyHelper.ProcessXcopy(this.args.DeployFolder, this.args.TempPhysicalPath, logger); if (!isSuccess) { logger($"【Error】Copy `{this.args.DeployFolder}` to `{this.args.TempPhysicalPath}` fail"); throw new Exception($"Copy `{this.args.DeployFolder}` to `{this.args.TempPhysicalPath}` fail"); } //修改物理路径 var err = IISHelper.ChangePhysicalPath(this.args.Site1, this.args.Site2, this.args.TempPhysicalPath); if (!string.IsNullOrEmpty(err)) { logger($"【Error】Change `{this.args.SiteName}` physicalPath to `{this.args.TempPhysicalPath}` fail"); throw new Exception($"【Error】Change `{this.args.SiteName}` physicalPath to `{this.args.TempPhysicalPath}` fail"); } //回收一下 var r1 = ProcessHepler.RunAppCmd($"recycle apppool /apppool.name:\"{this.args.ApplicationPoolName}\"", logger); logger($"recycle apppool /apppool.name:{this.args.ApplicationPoolName} ===> {(r1 ? "Success" : "Fail")}"); return; } try { if (args.UseOfflineHtm) { try { var createErr = IISHelper.CreateAppOffineHtm(this.args.AppFolder); if (!string.IsNullOrEmpty(createErr)) { logger($"【Error】Create app_offline.htm to [{this.args.AppFolder}] Fail:[{createErr}]"); return; } logger($"create app_offline.htm to [{this.args.AppFolder}] Success"); //创建了app_offline.htm成功后 iis会解除占用 //执行copy if (args.UseTempPhysicalPath) { } else { base.Deploy(); } } finally { var deleteErr = IISHelper.DeleteAppOfflineHtm(this.args.AppFolder); if (!string.IsNullOrEmpty(deleteErr)) { logger($"【Error】delete app_offline.htm from [{this.args.AppFolder}] Fail:[{deleteErr}]"); } logger($"delete app_offline.htm from [{this.args.AppFolder}] Success"); } } else { base.Deploy(); } } catch (Exception exception) { logger("Copy File Fail :" + exception.Message); retryTimes++; logger("Wait 5Senconds to Retry :" + retryTimes); Thread.Sleep(5000); if (retryTimes > 3) { IISHelper.KillSiteProcess(args.SiteName); killPool(); logger("Wait 5Senconds to Try deploy again"); Thread.Sleep(5000); try { base.Deploy(); return; } catch (Exception) { logger("【Error】Retry Copy Limit "); throw; } } Deploy(); } }
public override string DeployExcutor(FormHandler.FormItem fileItem) { var projectPath = Path.Combine(Setting.PublishWindowServicePathFolder, _serviceName); _projectPublishFolder = Path.Combine(projectPath, !string.IsNullOrEmpty(_dateTimeFolderName) ? _dateTimeFolderName : DateTime.Now.ToString("yyyyMMddHHmmss")); EnsureProjectFolder(projectPath); EnsureProjectFolder(_projectPublishFolder); var deployFolder = string.Empty; try { var _zipFile = Path.Combine(_projectPublishFolder, fileItem.FileName); using (var fs = new FileStream(_zipFile, FileMode.Create, FileAccess.Write)) { fs.Write(fileItem.FileBody, 0, fileItem.FileBody.Length); } if (!File.Exists(_zipFile)) { return("publish file save fail"); } #if NETCORE Log("netcore agent version ==>" + Version.VERSION); #else Log("netframework agent version ==>" + Version.VERSION); #endif Log("upload success ==>" + _zipFile); //解压 try { Log("start unzip file"); ZipFile.ExtractToDirectory(_zipFile, _projectPublishFolder); } catch (Exception ex) { return("unzip publish file error:" + ex.Message); } Log("unzip success ==>" + _projectPublishFolder); deployFolder = findUploadFolder(_projectPublishFolder, true); if (!Directory.Exists(deployFolder)) { return("unzip publish file error,Path not found:" + deployFolder); } //查找 Windows Service 里面是否存在该服务 var service = WindowServiceHelper.GetWindowServiceByName(this._serviceName); if (!string.IsNullOrEmpty(service.Item2)) { return(service.Item2); } if (service.Item1 == null) { Log($"windowService : {_serviceName} not found,start to create!"); //创建发布目录 var firstDeployFolder = string.IsNullOrEmpty(_physicalPath) ? Path.Combine(projectPath, "deploy") : _physicalPath; EnsureProjectFolder(firstDeployFolder); if (Directory.Exists(firstDeployFolder)) { Log($"deploy folder create success : {firstDeployFolder} "); } else { return($"DeployFolder : {firstDeployFolder} create error!"); } //复制文件到发布目录 CopyHelper.ProcessXcopy(deployFolder, firstDeployFolder, Log); Log($"copy files success from [{deployFolder}] to [{firstDeployFolder}]"); //部署windows service var execFullPath = Path.Combine(firstDeployFolder, _serviceExecName); if (!File.Exists(execFullPath)) { try { Directory.Delete(firstDeployFolder, true); } catch (Exception) { } return($"windows service exec file not found : {execFullPath} "); } //安装服务 Log($"start to install windows service"); Log($"service name:{_serviceName}"); Log($"service path:{execFullPath}"); Log($"service startType:{(!string.IsNullOrEmpty(_serviceStartType) ? _serviceStartType : "Auto")}"); Log($"service description:{_serviceDescription ?? string.Empty}"); try { if (_useNssm) { var rt = ServiceInstaller.NssmInstallAndStart(_serviceName, _param, execFullPath, _serviceStartType, _serviceDescription, Log); if (!rt) { return("use nssm install windows service fail"); } } else { ServiceInstaller.InstallAndStart(_serviceName, _serviceName, execFullPath + (string.IsNullOrEmpty(_param) ? "" : " " + _param), _serviceStartType, _serviceDescription); } Log($"install windows service success"); Log($"start windows service success"); return(string.Empty); } catch (Exception e2) { Thread.Sleep(5000); var isStart = WindowServiceHelper.IsStart(_serviceName); if (isStart) { Log($"install windows service success"); Log($"start windows service success"); return(string.Empty); } return($"install windows service fail:" + e2.Message); } } var projectLocationFolder = string.Empty; var projectLocation = WindowServiceHelper.GetWindowServiceLocation(this._serviceName); if (string.IsNullOrEmpty(projectLocation)) { return($"can not find executable path of service:{_serviceName}"); } //处理使用 nssm 安装的 Windows 服务程序 if (projectLocation.EndsWith("nssm.exe", true, CultureInfo.CurrentCulture)) { Log("service is installed by NSSM process."); var _nssmOutput = ""; var rt = ProcessHepler.RunExternalExe(projectLocation, $"get {_serviceName} Application", output => { _nssmOutput += Regex.Replace(output, @"\0", ""); }); if (!rt || string.IsNullOrEmpty(_nssmOutput.Trim())) { return($"can not find real executable path of nssm service:{_serviceName}"); } projectLocation = _nssmOutput; } Log($"project location:{projectLocation}"); try { projectLocation = projectLocation.Replace("\"", ""); projectLocationFolder = new FileInfo(projectLocation).DirectoryName; if (!Directory.Exists(projectLocationFolder)) { //如果目录不存在 那么就重新建立 EnsureProjectFolder(projectLocationFolder); } } catch (Exception) { return("ServiceFolder is not correct ===> " + projectLocationFolder); } Arguments args = new Arguments { DeployType = "WindowsService", BackupFolder = Setting.BackUpWindowServicePathFolder, AppName = _serviceName, AppFolder = projectLocationFolder, DeployFolder = deployFolder, WaitForWindowsServiceStopTimeOut = _waitForServiceStopTimeOut, BackUpIgnoreList = this._backUpIgnoreList, NoBackup = !Setting.NeedBackUp }; if (_serviceName.ToLower().Equals("antdeployagentwindowsservice")) { return(UpdateSelft(args)); } Log("Start to deploy Windows Service:"); Log("ServiceName ===>" + _serviceName); Log("ServiceFolder ===> " + projectLocationFolder); if (_isNoStopWebSite) { args.NoStop = true; args.NoStart = true; } var ops = new OperationsWINDOWSSERVICE(args, Log); try { ops.Execute(); try { //如果是增量的话 要把复制过来 if (_isIncrement) { Log("Increment deploy start to backup..."); //projectLocation.Item1 转到 increment 的目录 var incrementFolder = Path.Combine(_projectPublishFolder, "increment"); EnsureProjectFolder(incrementFolder); DirectoryInfo directoryInfo = new DirectoryInfo(projectLocationFolder); string fullName = directoryInfo.FullName; if (directoryInfo.Parent != null) { fullName = directoryInfo.Parent.FullName; } CopyHelper.DirectoryCopy(projectLocationFolder, incrementFolder, true, fullName, directoryInfo.Name, this._backUpIgnoreList); Log("Increment deploy backup success..."); } } catch (Exception ex3) { Log("Increment deploy folder backup fail:" + ex3.Message); } Log("Deploy WindowsService Execute Success"); } catch (Exception ex) { try { //ops.Rollback(); return($"publish to WindowsService err:{ex.Message}"); } catch (Exception ex2) { return($"publish to WindowsService err:{ex.Message},rollback fail:{ex2.Message}"); } } return(string.Empty); } catch (Exception ex) { return(ex.Message); } finally { if (!string.IsNullOrEmpty(deployFolder) && Directory.Exists(deployFolder)) { new Task(() => { try { Directory.Delete(deployFolder, true); } catch (Exception) { //ignore } }).Start(); } } }