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

时间:2020-10-01 11:34:20

标签: c# powershell jenkins console-application msdeploy

将使用过的Jenkins自动化服务器。

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

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

主要问题是控制台应用程序必须始终运行(有无尽的循环),并且它显示有关内部进程的重要信息。管理员可以随时使用管理员帐户登录,并查看控制台窗口中是否显示任何错误/警告。

我现在所拥有的:

"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 仅包含杀死正在运行的进程的脚本(运行良好)

run.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 在适当用户下在后台启动(这是预期的),我看不到控制台窗口,也不是我所期望的。

第二,当MsDeploy完成部署后,它会杀死远程计算机上的powershell进程,并且 D:\ Dev \ ConsoleApp.exe 也以父进程结束。

对于我来说,应该将控制台应用程序转换为Windows服务,然后部署和运行它就没有问题。但是客户希望看到内部包含信息的控制台窗口,我现在正在调查中。

1 个答案:

答案 0 :(得分:0)

除了通过Windows Scheduler创建任务以运行控制台应用程序(似乎由用户自己运行)以外,似乎没有其他方法。

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

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 Scheduler任务

run.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