【问题标题】:Pre/Post build event for windows service. Best practiceWindows 服务的预/后构建事件。最佳实践
【发布时间】:2013-11-12 19:31:02
【问题描述】:

有一个 Windows 服务,需要通过项目构建重新创建它。

活动前:

sc 查询“服务”| findstr /i 运行 |如果 "%errorlevel%"=="0" (sc 停止“服务”)

sc 查询“服务”| findstr /i 运行 |如果 "%errorlevel%"=="0" (sc 删除“服务”)

活动后:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe $(目标路径)

网络启动“服务”

但我有类似的问题

错误 1 ​​命令 "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe D:...\bin\Debug\Host.exe

net start "Service" " 退出,代码为 2。主机

有什么帮助吗?

【问题讨论】:

    标签: visual-studio windows-services pre-build-event prebuild build-events


    【解决方案1】:

    我也面临同样的问题。在我的情况下,当您尝试使用sc stop "Service" 命令停止服务已经处于停止状态时,就会发生这种情况。

    如果在执行命令时出现错误,那么命令 shell 返回非零值(主要是 1 或整数错误代码)作为返回代码,Visual Studio 会根据该代码停止进一步的构建过程。

    由于服务已经处于停止状态,所以我们想要的是 Visual Studio 应该简单地忽略返回码。您可以通过以下任何一种方式实现它。只需将其附加到预构建事件代码的末尾即可:

    SET ERRORLEVEL = 0
    

    或者

    EXIT 0
    

    即使在服务已经处于停止状态时出现任何错误,这也会强制返回 0(成功)代码。所以我完整的 Pre-build 事件代码如下所示:

    IF "Debug" == "$(ConfigurationName)" ( 
       sc query "W3SVC" | findstr "RUNNING" &  if %errorlevel% == 0 (net stop "World Wide Web Publishing Service")
       EXIT 0
    

    我的意图是停止 IIS 服务仅用于调试构建。

    【讨论】:

    • 在这种情况下将错误级别设置为 0 是一种给我的灵魂带来纯粹快乐的解决方案。不错的解决方案!
    【解决方案2】:

    不要忘记,构建事件中的脚本实际上只不过是 shell 脚本,因此如果不使用 [双] 引号括起来,路径(或程序集等)中的空格会搞砸。

    我所做的是在 shell 中使用宏 ${TargetPath} 等,输入的命令与它们将被扩展完全一样,首先确保它是正确的。在那里你会看到空间问题是否已经影响到你。

    我同意 VS 界面并没有给出很多具体的反馈,但公平地说,它实际上只是分叉到一个 shell,并显示 shell 完成后返回什么与所有行。

    因此,一行上的错误级别(VS 的“退出代码”)被抛出以作为最后的摘要错误级别。

    这是我放在项目根目录中的 2 个批处理文件,“如果较新则复制”到输出目录,然后在命令行上运行:

    .\startDeploy.bat
    
    C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe SomeService.exe
    net start "Some Server"
    

    ...和...

    .\stopDeploy.bat
    
    net stop "Some Server"
        C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe /LogToConsole=true /u SomeService.exe
    

    如果您有更好的方法(我喜欢您使用 sc),那么只需冲洗、起泡、重复即可。当您确定一切正常时,然后转换为构建事件窗口。在我准备好部署之前,我不会这样做。

    【讨论】:

      【解决方案3】:

      这对我有用...

      "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe" /u $(TargetFileName)
      "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe" $(TargetFileName)
       net start "Replace With Service Name"
      

      我将这些命令放在 Build Events 的 Post-Build 部分。

      第一行将卸载您的服务的预先存在的实例。如果服务不存在,这不会失败,因此无需先查询服务。您也不需要停止服务,卸载会自动完成。

      第二行将安装/重新安装您的服务。

      第三行将启动服务。 确保将其更改为不带任何文件扩展名的服务名称。

      希望这会有所帮助。

      【讨论】:

      • 如果服务当前正在运行,则构建后事件不会受到影响,因为该进程当前正在使用中。因此,它会失败。您应该先添加一个预构建事件来停止服务。
      • 就像我说的那样,它对我有用,在我的情况下,它确实会自动命中并停止服务。所有情况都不相同,所以仅仅因为它可能不适用于您的情况并不意味着它不是其他人的解决方案。感谢您的反对票。 =\
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 1970-01-01
      • 2012-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多