0

We want to Stop our windows Service before we rebuild it, Then Build the new version, then Copy it to a specified folder (due to the configuration changes putting the exe in different bin folders). then Restart the windows service. It Sounds Simple but the main problem we're having is stopping the service doesn't immediately release the file locks. Causing the build to fail ever other time. (once to stop the service and once to actually copy and restart it)

Currently as stated we do have a way that works exactly 50% of the time. It is however annoying to have to build twice every time we make a change to the solution. The current way is build events on the project level.

The Prebuild Looks like this:

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
net start | find "ServiceHost"
if Not ERRORLEVEL 1 InstallUtil.exe -u 
$(ProjectDir)bin\Current\ServiceHost.exe
Exit /b 0

and the PostBuild Looks Like This:

cd $(ProjectDir)bin
DEL Current\* /F /Q /S
xcopy $(Configuration) Current
cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
InstallUtil.exe $(ProjectDir)bin\Current\ServiceHost.exe
net start ServiceHost
Exit /b 0

There is also the problem of initial creation of the "Current" Folder as our source control doesn't keep the Bin folder. we could add a mkdir current command in there to fix this. if there is a better way to update the service every build your advice would be appreciated.

Dominic H
  • 39
  • 12
  • Perhaps something like [this](https://stackoverflow.com/a/1672375/2957232) to wait a certain amount of time before it attempts to continue after stopping the service? I've never done this before and did not test this. TBH I'm not even sure it's a good approach, so I won't post it as an actual answer. – Broots Waymb Jul 02 '19 at 16:55
  • We've already tried timeout and sleep commands. They dont seem to work as it can take anywhere from 10 to 40 seconds to release resources. also it doesnt act like its actually waiting that long before actually building – Dominic H Jul 02 '19 at 17:03
  • You could always write up an external tool that could stop the service, wait until it's available, then trigger the build programatically and restart when finished. Although I'm 0% sure whether that's overkill or not. – Broots Waymb Jul 02 '19 at 17:06
  • Have you tried using "net stop" in your prebuild step? – slig_3 Jul 02 '19 at 18:28
  • I usually use different environment when build and when deploy as a real service. Its is good to have some way to debug the service as a standard console app in development environment and then deploy as a service in test/production – Felice Pollano Jul 02 '19 at 19:00
  • Why would you like to install a win service on the local machine? https://stackoverflow.com/questions/7764088/net-console-application-as-windows-service –  Jul 02 '19 at 19:07
  • @dfhwze We are using the service to host web endpoints for a front end client. our systems are the dev environments so any changes we make to the services need to be available immediately to our copy of the client (connecting to localhost) – Dominic H Jul 02 '19 at 19:14
  • I get that, but a console app would also allow for the front-end to connect on localhost. I don't see the benefits of installing it as windows service on the localhost for devs to debug the system. –  Jul 02 '19 at 19:18
  • @dfhwze Is is also subscribed to mq messages and needs to be running constantly. it would be annoying to have to keep the console app open. also debugging is not an issue because we log any errors the service catches into its own log file and email message. – Dominic H Jul 02 '19 at 19:45
  • Can your service take longer than 30 seconds to stop? If so NET STOP may fail. You may need to loop several times on NET STOP. – CoreTech Jul 02 '19 at 22:23

1 Answers1

0

I have a solution that works. its not ideal but it does seem to work 100% of the time

Prebuild:

net stop ServiceHost
:delete
cd $(ProjectDir)
rmdir /s /q $(ProjectDir)bin\Current
echo delete Error Level %ERRORLEVEL%
goto checkDelete
:checkDelete
cd $(ProjectDir)bin\Current
echo check Error Level %ERRORLEVEL%
if %ERRORLEVEL% == 1 (GOTO end) else (GOTO retry)
:retry
echo Prebuild Retry after 5 seconds
powershell -command "Start-Sleep -s 5"
GOTO delete
:end
echo Prebuild Terminate
Exit /b 0

Post Build:

cd $(ProjectDir)bin
:copy
mkdir Current
xcopy $(Configuration) Current
echo PostBuild  Error Level %ERRORLEVEL%
if not %ERRORLEVEL% == 0 (GOTO copy)
echo starting service
net start ServiceHost
Exit /b 0
Dominic H
  • 39
  • 12