我正在寻找关于我正在构建的这个小系统的整体架构的一些指导。
目前,我有一个通过xcopy部署(和更新)到一些服务器的应用程序。这适用于更新代码,但它不能很好地更新代码的执行周期,因为它被设置为每小时运行一次的Windows计划任务。 xcopy替换效果很好,因为我可以从本地计算机运行更新,并将新的exe文件推送到所有服务器。在接下来的一小时,任务调度程序将运行新的exe。
我想改变它以这种方式工作。
我的应用程序作为Windows服务运行,并使用System.Threading.Timer等待给定的持续时间,然后执行代码。这样,进程的一部分可以检查数据库,并在必要时减少给定服务器的执行时间。
那里的问题是,由于.exe将作为服务运行,因此不允许通过xcopy轻松更新,因为该文件将一直在使用。
在作为Windows服务运行时,有关如何设置此功能以便能够轻松进行xcopy更新的任何想法?这甚至可能吗?
答案 0 :(得分:2)
您可以停止服务,然后复制文件,然后从批处理文件启动服务:
SET SOURCEDIR=\\coastappsdev\wwwroot\ClearTrac\Setup\03_Staging\ClearTracAutoSend\bin
SET SERVICE_HOME=C:\INETPUB\WWWROOT\ClearTracAutoSend
SET SERVICE_EXE=ClearTracAutoSend.exe
SET INSTALL_UTIL_HOME=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
:STOP THE SERVICE:
SC \\targetServer STOP ClearTracAutoSend
:COPY THE FILES:
MD %SERVICE_HOME%
XCOPY %SOURCEDIR%\*.* %SERVICE_HOME%\*.* /E /R /Y
set PATH=%PATH%;%INSTALL_UTIL_HOME%
cd %SERVICE_HOME%
echo Uninstalling AutoSend Service...
installutil /u %SERVICE_EXE%
cd %SERVICE_HOME%
echo installing AutoSend Service...
installutil /i %SERVICE_EXE%
:START THE SERVICE:
SC \\targetServer ClearTracAutoSend
pause
这可能不是远程的最佳解决方案,我不知道如何远程运行installutil。我们RDP到服务器并运行批处理文件。
答案 1 :(得分:1)
如何将更新代码移出服务,只需将下一次迭代的时间检查到自己的程序集中。在每次运行之前动态加载然后卸载它。我也想知道Quartz.net是否对你有用。
答案 2 :(得分:0)
你可以让你的Service Spawn成为一个子进程(exe)并等待它退出。
通过这种方式,您的应用程序可以轻松更新,因为它已加载,运行然后退出,只要您不需要更新服务,就可以轻松完成。
如果想要更加棘手,可以将其设置为程序集(dll),即通过将dll加载到内存中然后执行它来加载内存,或者可以设置它运行的ShadowCopy目录。
答案 3 :(得分:0)
如果您愿意停止服务,推送代码并启动服务,那么您有几个选择。
最好的是Powershell或MsBuild。
如果您担心时间问题,只需将服务设置为在启动时运行一次(或startTime +某个时间间隔),然后每小时运行一次。
如果你真的需要这个服务才能保持运行但能够在运行之间更改代码,你需要一些Managed Extensibility Framework(MEF),它允许将DLL代码存储在某个地方并仅加载在运行时,所以可以在不重新启动的情况下对其进行修改。
答案 4 :(得分:0)
我最终使用了一些@ Decker97的解决方案,再加上一些PowerShell魔法:)
function global:new-process()
{
param ([string]$computer, [string]$commandline=$(throw "Command line required."))
$path = "\\$computer\root\cimv2:Win32_Process"
$mc = new-object System.Management.ManagementClass $path
$cmdargs = $commandline,$null,$null,0
$ret = $mc.InvokeMethod("Create", $cmdargs)
if ($ret -eq 0) {
write-host "Created Process ID: $($cmdargs[3])"
}
else {
write-host "Error $ret creating process."
}
$mc.Dispose()
}
$serverNames = Get-Content C:\temp\servers.txt
foreach ($server in $serverNames)
{
write-host Updating $server
c:\windows\system32\sc.exe \\$server STOP Service
$source = "C:\Projects\Service\bin\Debug"
$dest = "\\" + $server + "\C$\Program Files\TargetFolder\TargetFolder"
ROBOCOPY.exe $source $dest /MIR /W:5 /R:1
new-process $server 'c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Installutil.exe /i /LogFile=install.out "C:\Program Files\TargetFolder\TargetFolder\serviceExecutable.exe"'
c:\windows\system32\sc.exe \\$server START Service
}
脚本使用服务控制来尝试停止服务。
然后使用robocopy将文件复制到服务器。
然后使用WMI和Powershell在服务器上远程调用“installutil”。
然后使用服务控制启动服务。