在Web服务器上部署可执行进程的最佳方法是什么?

时间:2009-12-14 11:07:32

标签: c# .net deployment

最初的问题:

这个问题的标题可能有点笨拙,但情况如下:

我在我的服务器上部署了一个.NET Web项目。它仍处于测试阶段,所以发布了大量的释放和重新发布。

我还在同一个VS解决方案(称为“admin.exe”)中编写了一个C#可执行文件,该解决方案在服务器的后台运行,定期执行某些业务规则完整性检查,并对其中的警告表进行适当的插入。 DB。

问题是:部署此应用程序的最佳方式是什么,以便每当我发布新版本时它都会更新?它应该在不同版本之间一直运行,所以理想情况下我想要某种设置,其中shutdown-deploy-startup过程涉及尽可能少的步骤。

谢谢!

编辑 - 赏金开始

到目前为止给出的答案是有用和有趣的,但没有给我一个清晰,简洁和优雅的解决方案。请不要认为我对部署项目有广泛的了解,因为我没有。 Bounty会找到能够提供以下解决方案的人:

  1. 发布最新版本的网站;
  2. 关闭服务器上运行的任何admin.exe实例;
  3. 更新admin.exe;
  4. 启动admin.exe;
  5. 上述所有内容应优先一步完成,或尽可能少的步骤,因为它将在产品的整个生命周期内重复进行;和
  6. 以上所有内容均应优先完成,无需安装任何第三方软件。
  7. 感谢您的帮助!

    次要编辑 - 澄清

    我认为到目前为止提供的很多解决方案都高估了问题的复杂性,所以让我澄清一下:要部署的所有内容,只需部署在一台计算机上,也很高兴Visual Studio提供所有源代码。我只需要(1)将网站发布到web文件夹,(2)关闭,重新安装并重新启动同一服务器上的admin.exe。有没有一个简单的方法一步到位?是否可以使用VS部署项目完成?

11 个答案:

答案 0 :(得分:3)

听起来您需要查看自定义MSBuild脚本以进行部署。

MSBuild不仅仅是构建解决方案。您也可以使用它来复制文件并更新它们。执行此任务的一个很好的资源是MSBuild社区任务here

然后,您可以在部署网站部署的同时包括后台进程的部署。

另一种方法可能是使用Windows PowershellPSExec来远程执行复制和更新命令。

使用Hudson等持续集成服务器,这两种方法都可以很好地自动化。我有一个构建过程,它自动监视我的源代码存储库,构建程序,部署到登台服务器,运行验收测试,然后部署到预览框。我有另一个(手动)作业,只需点击一下即可部署此预览版本,最大限度地减少停机时间,并且(通常)减少错误命令的错误。

答案 1 :(得分:3)

“正确”的方式可能是设置部署脚本和安装程序,但只需单击Visual Studio中的发布并跳过远程桌面就可以在开发过程中更加方便。

我有一个管理员网络应用程序,它充当命令行应用程序的前端 - 与您正在做的略有不同,但同样的解决方案应该有效。

只需在admin web app中添加对控制台项目的引用即可。即使您没有在控制台项目中调用任何方法,该引用也会导致在您发布管理网站时重建和上载控制台应用程序。

添加到网络应用程序的简单启动/停止页面负责第2步和第2步。 4 - Mine调用Process.Start()/ Process.Kill(),尽管你显然可以选择更干净的关闭,具体取决于admin.exe的设置。

以下是我的开始/停止页面中的代码 - 我将它们设置为Web服务方法(以方便您可能不需要的某些监控内容),但它们应该可以通过简单的按钮单击调用方法。请注意,服务帐户需要运行/停止进程的权限 - 在开发框中,最简单的选项是将iis设置为以管理员用户身份运行,而不是默认服务帐户。

    private void KillProcess(string name)
    {
        var binpath = Server.MapPath("~/bin");
        var pp2 = Process.GetProcesses();

        var pp = from p in pp2 where p.ProcessName.Contains(name) && !p.ProcessName.Contains("vshost") select p;
        foreach (var p in pp)
        {
            p.Kill();
        }
    }

[WebMethod]
    public void StartQueueRunner()
    {
        var binpath = Server.MapPath("~/bin");
        System.Diagnostics.Process.Start(Path.Combine(binpath, "TwoNeeds.QueueRunner.exe"));
    }

[WebMethod]
    public void StartQueueRunner()
    {
        var binpath = Server.MapPath("~/bin");
        System.Diagnostics.Process.Start(Path.Combine(binpath, "TwoNeeds.QueueRunner.exe"));
    }

答案 2 :(得分:2)

可能有一种更清洁的方式,但可能将其安装为Windows服务,然后使用installutil.exe编写安装/卸载命令的脚本。然后只需更新服务所在的文件夹并为每次更新重新运行脚本?

优秀的服务教程here

希望这有帮助

答案 3 :(得分:2)

我建议您编写一个可以在PC上运行的脚本,通过网络进行部署(这样您就不必每次都登录到目标计算机)。我使用msbuild完成了它,但你真的只需要一个批处理文件。

我假设您的管理进程正在运行Windows服务(无论如何,将其作为服务运行是有意义的),因此您将像这样部署它(这是msbuild脚本的一部分 - 您可以使用用户名删除位和密码,如果你不需要它):

<ItemGroup>
    <ReleaseFiles Include="localPath\bin\*.dll"/>
    <ReleaseFiles Include="localPath\bin\*.exe"/>
    <ReleaseFiles Include="localPath\bin\*.pdb"/>
    <ReleaseFiles Include="localPath\bin\*.config"/>   
</ItemGroup>

<Target Name="Release">
    <Message Text="Installing Admin on $(DeploymentMachine) as user $(User)"/>
    <Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) stop &quot;Admin&quot;" />
    <Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) delete &quot;Admin&quot;" />
    <Delete ContinueOnError="true" Files="\\$(DeploymentMachine)\C$\path-to-admin\*.*"/>
    <MakeDir Directories="\\$(DeploymentMachine)\C$\path-to-admin"/>
    <Copy SourceFiles="@(ReleaseFiles)" DestinationFiles="@(ReleaseFiles->'\\$(DeploymentMachine)\C$\path-to-admin\%(RecursiveDir)%(Filename)%(Extension)')" />
    <Exec Command="sc.exe \\$(DeploymentMachine) create &quot;Admin&quot; binpath= &quot;C:\path-to-admin\admin.exe&quot; start= auto obj= $(User) password= $(Password)"  />
    <Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) start &quot;Admin&quot;" />
</Target>

部署IIS网站通常会有点痛苦,但是如果您在目标计算机上设置了所有内容,那么可能只需通过网络复制文件(再次使用\ DeploymentMachine \ share或\ DeploymentMachine \ C $ \路径寻址)。

不幸的是,部署永远不会很好也不优雅:(

如果您需要澄清任何事情,请告诉我

答案 4 :(得分:1)

这是一个讨厌的想法。如果你是admin.exe没有做任何太难的核心,为什么不扔进IIS?要编写C#Web服务,您可能不需要进行太多更改。

为了确保重复调用它,您可以使用各种方法,例如Windows Scheduler,每分钟运行一次wget。使用文件锁保持并发副本,如果完成时间超过一分钟。

这将使您的部署像文件副本(FTP)一样简单。我甚至认为你在推送C#DLL时不需要重启IIS。如果这样做,您可以通过SSH编写脚本。

答案 5 :(得分:0)

对我而言,您的问题听起来很像SharePoint通过在每个WFE中运行的Timer服务,stsadm排队管理任务,该服务出列并运行它们等解决的部署问题。

我要做的是

  • 编写在每个WFE中运行的服务
  • 编写一个小型自定义“stsadm”工具,以便您可以将任务排队,指定他们何时需要运行等等。

另一种方法:如何使用普通的Windows任务计划程序?查看here,您可以轻松地远程排队任务。

答案 6 :(得分:0)

我会写一个命令行应用程序来完成所有这些工作。

这是一个粗略的例子:

Site.api.publish();
admin.api.shutdown();
while(shell.status("admin.exe") == true) {}; //still running
file.replace("admin.exe", "path-to-compile\admin.exe");
shell.run("admin.exe");

你可能会明白这一点。如果您希望它自动执行,只需使用任务计划每天调用它,或者通常您需要它。

答案 7 :(得分:0)

在服务器/网站上存储最新版本的在线项目。例如:在version.txt中,值为“2.1.0”,或者如果您也有访问权限,则查询数据库。

在客户端上运行的应用程序将定期读取version.txt文件的内容,然后与内置(自我)版本号进行比较。

  • 如果检测到补丁或次要版本,例如2.1.123,则会悄悄地旋转第二个应用程序(updater.exe)
    • 进行升级,
    • 它将从server / web下载更新的(首选压缩)项目。
    • 停止所有正在运行的实例。
    • 解压缩内容。
    • 备份现有文件(重命名)
    • 复制/安装新版本的项目,
    • 启动应用程序(成功重启应用程序后,它将删除自己的备份文件)。
  • 如果检测到主要版本,例如:3.0.0
    • 通知用户有重大升级
    • 如果用户接受,请下载安装程序
    • 运行完整的安装程序更新

这有帮助吗?

答案 8 :(得分:0)

用于Web应用程序的VS部署项目并不容易掌握,有些不可靠。我的建议是什么:

  1. 将Admin.exe修改为.NET Windows服务。看看为什么你需要这样做。
  2. 使用sc.exe,InstallUtil.exe或安装程序构建服务(如installer.codeeffects.com)在每次部署时快速重新安装服务。顺便说一句,如果我没记错的话,可以在installer.codeeffects.com上下载一个VS示例代码,了解如果您是新手来构建.NET Windows服务。
  3. 部署可以这样完成(假设您在自动化方面的需求很少,而且几乎可以手动部署):

    运行上述任一工具以首先重新安装您的服务。 sc.exe和InstalUtil.exe工具支持命令行。因此,如果您的Web应用程序,VS和服务在同一台计算机(您的开发计算机,我假设?)上运行,您可以右键单击VS中的Web项目,选择“属性”并设置构建前或构建后命令那里的Build Events选项卡。这样,您的VS可以在发布Web应用程序之前自动重建并重新安装您的服务。这就是为什么exe程序在你的情况下不好的主要原因,Windows服务会更好地为你服务。

    然后部署您的网络应用程序(假设它已按照上面的讨论进行构建)。这里没有大佬,只需使用VS中的发布命令或移动您的Web应用程序的所有文件,除了.cs文件,/ Properties /和/ obj /文件夹。或者,如果从项目文件夹运行,只需右键单击主页面并选择“在浏览器中查看” - 这将通过VS启动运行时而无需启动调试器。

    很抱歉这么冗长的帖子。我是否正确理解了您的问题和说明? :)

答案 9 :(得分:0)

如果在部署后点击admin.exe怎么办?然后在您的admin.exe中,在检查业务规则的完整性之前,检查an update is available.如果是,请更新,然后继续检查。

答案 10 :(得分:0)

为了简化操作并确保我能够回滚所有内容,我将创建一个执行以下操作的PowerShell脚本:

  1. 停止应用程序池。
  2. 将当前的网络应用程序复制到 “历史文件夹”,以便您可以回滚 如果需要,可以使用该版本
  3. 部署新的网络应用
  4. 停止当前的admin.exe 服务
  5. 卸载admin.exe 执行Uninstall.bat(这是 对Windows服务很常见)
  6. 将当前的admin.exe应用程序复制到 历史文件夹(见2)
  7. 将新的admin.exe复制到 正确的位置并运行install.bat
  8. 启动新服务
  9. 启动应用程序池
  10. 你可以在Powershell脚本中自动化所有这些(我唯一不确定的是应用程序池,但我很确定你可以这样做。)

    有关PowerShell的更多信息,请访问:http://arstechnica.com/business/news/2005/10/msh.ars/2