Last active
June 26, 2024 09:37
-
-
Save mrchief/4726433 to your computer and use it in GitHub Desktop.
MSBuild Script to deploy Windows Service to remote or local machine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Project DefaultTargets="CopyOutputs;DeployService" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> | |
<!-- These settings control what the service's name, description etc appear in services.msc task panel. --> | |
<PropertyGroup Label="ServiceMetaData"> | |
<ServiceName>ShinyNewService</ServiceName> | |
<ServiceDisplayName>Shiny New Service</ServiceDisplayName> | |
<ServiceDescription>A shiny new service, that changes the world for the greater good.</ServiceDescription> | |
</PropertyGroup> | |
<Choose> | |
<When Condition="'$(DeploymentServerName)' == ''"> | |
<PropertyGroup> | |
<!-- You can choose any path here. For convenience, I'm using C: --> | |
<DeploymentFolder>C:\$(ServiceName)</DeploymentFolder> | |
</PropertyGroup> | |
</When> | |
<Otherwise> | |
<PropertyGroup> | |
<!-- should be in \\serverName format--> | |
<DeploymentServer Condition="'$(DeploymentServerName)' != ''">$(DeploymentServerName)</DeploymentServer> | |
<DeploymentFolder>$(DeploymentServer)\C$\$(ServiceName)</DeploymentFolder> | |
<!-- 4:5:4 => Planned: Application: Upgrade. For more reason codes, run "sc stop" --> | |
<DeploymentReason>4:5:4</DeploymentReason> | |
</PropertyGroup> | |
</Otherwise> | |
</Choose> | |
<PropertyGroup> | |
<ProjectName>My.Services.ShinyNewService</ProjectName> | |
<ProjectFile>$(MSBuildProjectDirectory)\$(ProjectName).csproj</ProjectFile> | |
<ServiceExecutablePath>C:\$(ServiceName)\$(ProjectName).exe</ServiceExecutablePath> | |
</PropertyGroup> | |
<Target Name="DeployService"> | |
<Exec Command="safeServiceStop $(ServiceName) $(DeploymentServer) $(DeploymentReason)" /> | |
<Exec Command="safeServiceDelete $(ServiceName) $(DeploymentServer)" ContinueOnError="true" /> | |
<Exec Command="sc $(DeploymentServer) create $(ServiceName) binPath= "$(ServiceExecutablePath)" start= delayed-auto displayName= "$(ServiceDisplayName)"" /> | |
<Exec Command="sc $(DeploymentServer) description $(ServiceName) "$(ServiceDescription)"" /> | |
<Exec Command="safeServiceStart $(ServiceName) $(DeploymentServer) " ContinueOnError="true" /> | |
</Target> | |
<Target Name="CopyOutputs"> | |
<MSBuild Projects="$(MSBuildProjectFullPath)" | |
Properties="ImportProjectFile=true" Targets="Rebuild"> | |
<Output ItemName="ProjectOutputs" TaskParameter="TargetOutputs"/> | |
</MSBuild> | |
<!-- This is just for debugging purposes --> | |
<Message Text="%0a%0dProjectOutputs:%0a%0d @(ProjectOutputs,'%0a%0d ')" Importance="low" /> | |
<Message Text="Stopping Service..." /> | |
<!-- 4:5:4 => Planned: Application: Upgrade --> | |
<Exec Command="safeServiceStop $(ServiceName) $(DeploymentServer) $(DeploymentReason)" ContinueOnError="true" /> | |
<Message Text="Copying files..." /> | |
<Copy SourceFiles="@(ProjectOutputs)" | |
DestinationFolder="$(DeploymentFolder)" | |
SkipUnchangedFiles="true" | |
OverwriteReadOnlyFiles="true" /> | |
</Target> | |
<!-- | |
These elements will only be processed when in the context of the | |
above Target. This is because of the Condition constraint on these items | |
--> | |
<Import Project="$(ProjectFile)" Condition="'$(ImportProjectFile)'=='true'" /> | |
<!-- | |
Here we need to override the Build target with our own that will | |
generate the correct results. | |
--> | |
<Target Name="Rebuild" | |
Condition="'$(ImportProjectFile)'=='true'" | |
DependsOnTargets="$(BuildDependsOn)" | |
Outputs="@(AllOutputs->'%(FullPath)')" > | |
<CreateItem Include="$(OutputPath)\**\*"> | |
<Output ItemName="AllOutputs" TaskParameter="Include"/> | |
</CreateItem> | |
<Message Text="Custom build invoked!" Importance="high"/> | |
</Target> | |
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
:: Script authored by Hrusikesh Panda (inspired from safeServiceStop script by Erik Falksen) | |
IF [%1]==[] GOTO usage | |
IF NOT "%2"=="" SET server=%2 | |
SC %server% query %1 >NUL | |
IF errorlevel 1060 GOTO ServiceNotFound | |
IF errorlevel 1722 GOTO SystemOffline | |
IF errorlevel 1001 GOTO DeletingServiceDelay | |
:ResolveInitialState | |
SC %server% query %1 | FIND "STATE" | FIND "RUNNING" >NUL | |
IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService | |
SC %server% query %1 | FIND "STATE" | FIND "STOPPED" >NUL | |
IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppedService | |
SC %server% query %1 | FIND "STATE" | FIND "PAUSED" >NUL | |
IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline | |
echo Service State is changing, waiting for service to resolve its state before making changes | |
sc %server% query %1 | Find "STATE" >NUL | |
ping -n 2 127.0.0.1 > NUL | |
GOTO ResolveInitialState | |
:StopService | |
echo Stopping %1 on %server% | |
sc %server% stop %1 %3 >NUL | |
GOTO StoppingService | |
:StoppingServiceDelay | |
echo Waiting for %1 to stop | |
ping -n 2 127.0.0.1 > NUL | |
:StoppingService | |
SC %server% query %1 | FIND "STATE" | FIND "STOPPED" >NUL | |
IF errorlevel 1 GOTO StoppingServiceDelay | |
:StoppedService | |
echo %1 on %server% is stopped | |
GOTO DeleteService | |
:DeleteService | |
SC %server% delete %1 >NUL | |
:DeletingServiceDelay | |
echo Waiting for %1 to get deleted | |
ping -n 2 127.0.0.1 > NUL | |
:DeletingService | |
SC %server% query %1 >NUL | |
IF NOT errorlevel 1060 GOTO DeletingServiceDelay | |
:DeletedService | |
echo %1 on %server% is deleted | |
GOTO:eof | |
:SystemOffline | |
echo Server %server% is not accessible or is offline | |
GOTO:eof | |
:ServiceNotFound | |
echo Service %1 is not installed on Server %server% | |
exit /b 0 | |
:usage | |
echo Will cause a local/remote service to START (if not already started). | |
echo This script will waiting for the service to enter the started state if necessary. | |
echo. | |
echo %0 [service name] [system name] | |
echo Example: %0 MyService server1 | |
echo Example: %0 MyService (for local PC) | |
echo. | |
GOTO:eof |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
:: Tweaked version of the original script authored by Eric Falsken | |
IF [%1]==[] GOTO usage | |
IF NOT "%2"=="" SET server=%2 | |
SC %server% query %1 >NUL | |
IF errorlevel 1060 GOTO ServiceNotFound | |
IF errorlevel 1722 GOTO SystemOffline | |
:ResolveInitialState | |
SC %server% query %1 | FIND "STATE" | FIND "STOPPED" >NUL | |
IF errorlevel 0 IF NOT errorlevel 1 GOTO StartService | |
SC %server% query %1 | FIND "STATE" | FIND "RUNNING" >NUL | |
IF errorlevel 0 IF NOT errorlevel 1 GOTO StartedService | |
SC %server% query %1 | FIND "STATE" | FIND "PAUSED" >NUL | |
IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline | |
echo Service State is changing, waiting for service to resolve its state before making changes | |
sc %server% query %1 | Find "STATE" >NUL | |
ping -n 2 127.0.0.1 > NUL | |
GOTO ResolveInitialState | |
:StartService | |
echo Starting %1 on %server% | |
sc %server% start %1 >NUL | |
GOTO StartingService | |
:StartingServiceDelay | |
echo Waiting for %1 to start | |
ping -n 2 127.0.0.1 > NUL | |
:StartingService | |
SC %server% query %1 | FIND "STATE" | FIND "RUNNING" >NUL | |
IF errorlevel 1 GOTO StartingServiceDelay | |
:StartedService | |
echo %1 on %server% is started | |
GOTO:eof | |
:SystemOffline | |
echo Server %server% is not accessible or is offline | |
GOTO:eof | |
:ServiceNotFound | |
echo Service %1 is not installed on Server %server% | |
exit /b 0 | |
:usage | |
echo Will cause a local/remote service to START (if not already started). | |
echo This script will waiting for the service to enter the started state if necessary. | |
echo. | |
echo %0 [service name] [system name] | |
echo Example: %0 MyService server1 | |
echo Example: %0 MyService (for local PC) | |
echo. | |
GOTO:eof |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
:: Tweaked version of the original script authored by Eric Falsken | |
IF [%1]==[] GOTO usage | |
IF NOT "%2"=="" SET server=%2 | |
SC %server% query %1 >NUL | |
IF errorlevel 1060 GOTO ServiceNotFound | |
IF errorlevel 1722 GOTO SystemOffline | |
:ResolveInitialState | |
SC %server% query %1 | FIND "STATE" | FIND "RUNNING" >NUL | |
IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService | |
SC %server% query %1 | FIND "STATE" | FIND "STOPPED" >NUL | |
IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppedService | |
SC %server% query %1 | FIND "STATE" | FIND "PAUSED" >NUL | |
IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline | |
echo Service State is changing, waiting for service to resolve its state before making changes | |
sc %server% query %1 | Find "STATE" >NUL | |
ping -n 2 127.0.0.1 > NUL | |
GOTO ResolveInitialState | |
:StopService | |
echo Stopping %1 on %server% | |
sc %server% stop %1 %3 >NUL | |
GOTO StoppingService | |
:StoppingServiceDelay | |
echo Waiting for %1 to stop | |
ping -n 2 127.0.0.1 > NUL | |
:StoppingService | |
SC %server% query %1 | FIND "STATE" | FIND "STOPPED" >NUL | |
IF errorlevel 1 GOTO StoppingServiceDelay | |
:StoppedService | |
echo %1 on %server% is stopped | |
GOTO:eof | |
:SystemOffline | |
echo Server %server% is not accessible or is offline | |
GOTO:eof | |
:ServiceNotFound | |
echo Service %1 is not installed on Server %server% | |
exit /b 0 | |
:usage | |
echo Will cause a local/remote service to STOP (if not already stopped). | |
echo This script will waiting for the service to enter the stopped state if necessary. | |
echo. | |
echo %0 [service name] [system name] {reason} | |
echo Example: %0 MyService server1 {reason} | |
echo Example: %0 MyService (for local PC, DO NOT specify reason) | |
echo. | |
echo For reason codes, run "sc stop" | |
GOTO:eof |
Alternate explanation url: https://mrchief2000.wordpress.com/2017/02/10/deploying-windows-service-via-msbuild/
I got the following error:
[SC] ChangeServiceConfig2 (delayed autostart flag) FAILED 124:
The system call level is not correct.
which was resolved by changing start= delayed-auto
to start= auto
@mattumotu thanks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Could not it be better instead
use