2010-07-12 38 views
0

我正在寻找关于我正在构建的这个小系统的整体架构的一些指导。构建应用程序以定期在服务器上执行任务

目前,我有一个应用程序,通过xcopy部署(和更新)到几个服务器。这适用于更新代码,但它不适用于更新代码执行的周期,因为它设置为每小时运行一次的Windows计划任务。 xcopy替换效果很好,因为我可以从本地机器运行更新,并将新的exe文件推送到所有服务器。接下来的一个小时,任务调度器将运行新的exe。

我想改变它以这种方式工作。

我的应用程序作为Windows服务运行,并使用System.Threading.Timer等待给定的持续时间,然后执行代码。这样,进程的一部分可以检查数据库,并在必要时减少给定服务器的执行时间。

问题在那里,是因为.exe将作为服务运行,它不会允许通过xcopy轻松更新,因为该文件将始终处于使用状态。

有关我应该如何设置这个以便能够在作为Windows服务运行时轻松执行xcopy更新的想法?这甚至可能吗?

回答

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”。

然后使用服务控制来启动服务。

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发送到服务器并运行批处理文件。

+0

我正在从本地机器运行我当前的xcopy批处理文件,并将更新从我的机器推送到许多服务器。我想避免从服务器本身运行任何东西。 – Nate 2010-07-12 22:28:07

+0

除了'net stop'外,您可以使用'sc'在远程机器上启动/停止服务。 – 2010-07-12 23:14:17

+0

这意味着运行批处理文件的用户需要权限才能停止服务器上的服务,对不对?所以我需要一个活动目录帐户? – Nate 2010-07-13 03:11:54

0

你可以让你的服务生成一个子进程(exe)并等待它退出。

通过这种方式,您的应用程序可以轻松更新,因为它已加载,运行并退出,只要您不需要更新服务,这一切都非常简单。

如果想要更加棘手,可以将其设置为程序集(dll),即通过将内存加载到内存然后执行内存加载内存,或者您可以设置它运行的ShadowCopy目录。

1

如何将更新代码移出服务,只需将下一次迭代的时间检查到自己的程序集中。在每次运行之前动态加载,然后卸载它。我也想知道Quartz.net对你有用。

0

如果您打算停止服务,推送代码并启动服务,您有几个选项。

最好的应该是Powershell或MsBuild。

如果您关心计时,只需将服务设置为在启动时运行一次(或startTime +某个间隔),然后每小时运行一次。

如果你真的需要这个服务来保持运行,但是能够改变运行之间的代码,你需要一些Managed Extensibility Framework(MEF),它允许DLL代码存储在某个地方并且只在运行时加载,因此可以在不重启的情况下进行修改。

相关问题