MSDeploy 在远程服务器上部署 c# 控制台应用程序

MSDeploy deploy c# console application on remote server

这里会用到Jenkins自动化服务器。

我在部署过程中需要做的事情:

  1. 停止控制台应用程序
  2. 通过 MSDeploy 服务部署
  3. 运行 再次控制台应用程序

主要问题是控制台应用程序必须始终工作(有一个无限循环)并且它显示有关内部进程的重要信息。管理员可以随时在管理员帐户下登录并查看控制台中是否显示 error/warning window.

我目前拥有的:

"C:\Program Files\IIS\Microsoft Web Deploy V3\MSDeploy.exe" -verb:sync -preSync:runCommand=D:\Dev\tools\pre-deploy.cmd -postSync:runCommand="powershell -file D:\Dev\tools\run.ps1",waitInterval=3000 -source:contentpath="D:\Publish\" -dest:contentpath="D:\Dev",computername=https://somedomain:8172/MsDeploy.axd,username=adminuser,password=adminpassword,authtype=Basic -allowUntrusted=True -verbose

pre-deploy.cmd 仅包含用于终止 运行ning 进程(运行良好)

的脚本

运行.ps1包含下一个脚本

$username = 'adminuser'; 
$password = 'adminpassword'; 
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force; 
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword; 
$proc = Start-Process D:\Dev\ConsoleApp.exe 0 -Credential $credential -PassThru; 
$proc.WaitForExit();

首先,D:\Dev\ConsoleApp.exe 在适当的用户下在后台启动(这是预期的),我看不到控制台 window这不是我所期待的。

其次,当 MsDeploy 完成部署后,它会终止远程计算机上的 powershell 进程,并且 D:\Dev\ConsoleApp.exe 也会结束父进程。

我的应该是console应用转成windows服务,然后部署运行ning就没有问题了。但是客户希望看到控制台window里面有信息,我现在正在调查中。

除了通过 Windows 调度程序创建一个任务到 运行 控制台应用程序,似乎没有其他办法,就像用户自己 运行 一样。

要运行在你需要的特定用户下首先创建一些包装脚本

wrapper.ps1

param(
    [string] $UserName,
    [string] $Password,
    [string] $DestPath,
    [string] $Engine,
    [string] $EngineArgs
)

$securePassword = ConvertTo-SecureString $Password -AsPlainText -Force; 
$credential = New-Object System.Management.Automation.PSCredential $UserName, $securePassword; 
$proc = Start-Process powershell -ArgumentList "-noexit ""$DestPath\tools\run.ps1"" -UserName $UserName -DestPath """"$DestPath"""" -Engine """"$Engine"""" -EngineArgs $EngineArgs" -Credential $credential -PassThru;
$proc.WaitForExit();
exit 0

然后你需要创建Windows调度任务

运行.ps1

param(
    [string] $UserName,
    [string] $DestPath,
    [string] $Engine,
    [string] $EngineArgs
)

$A = New-ScheduledTaskAction -Execute "$DestPath$Engine.exe" -Argument $EngineArgs
$T = New-ScheduledTaskTrigger -Once -At (get-date).AddSeconds(10); $t.EndBoundary = (get-date).AddSeconds(60).ToString('s')
$S = New-ScheduledTaskSettingsSet -StartWhenAvailable -DeleteExpiredTaskAfter 00:00:30

$Task = New-ScheduledTask -Action $A -Trigger $T -Settings $S
$Task | Register-ScheduledTask -Force -TaskName "$Engine For Customer $EngineArgs" -User "$UserName"

#Fix Stuck BITS job

$A = New-ScheduledTaskAction -Execute "powershell.exe" -Argument '-command &{Get-BitsTransfer -AllUsers | Where-Object { $_.JobState -like "TransientError" } | Remove-BitsTransfer}'
$T = New-ScheduledTaskTrigger -Once -At (get-date).AddSeconds(10); $t.EndBoundary = (get-date).AddSeconds(60).ToString('s')
$S = New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter 00:00:40
Register-ScheduledTask -Force -user $UserName -TaskName "Fix Stuck BITS" -Action $A -Trigger $T -Settings $S
exit 0