I'm having a bit of trouble with an application i'm developing. Here's the scenario: I have two Windows Services (Service A and Service B) written in C#.
Service A is responsible to transfer data between two applications (using WebServices, FTP connections, etc). It's also responsible to update Service B.
Service B is responsible to update Service A and update a Web Application.
The basic operation of updates is (lets say this is the process to update service A, done by Service B):
- Check for updates through WebServices
- If there is a new version, stop the service (using C# ServiceController).
- Backup current files of the service (so I can do a Rollback if something goes wrong)
- Uninstall the service (using sc delete command)
- Download the updated files of the service (using FTP connection)
- Execute some SQL Server scripts, if exist
- Install the Windows Service (using sc create command)
- Start Service (using C# ServiceController)
Everything runs smoothly until step 7. I figured that the problem is that the user doing the update (the user that runs Service B) does not have permissions to create new windows services, so SC Create always returns something like "[SC] OpenSCManager FAILED 5: Access is denied" Note that I had both services running with LocalSystem Account. So, I figured that this account cannot create new Windows Services (correct me if I've assumed wrong).
After this I've created a new Windows User, just to run the services. The idea was to give this user the necessary permissions (to network shared, files and create services). However, this u开发者_StackOverflow社区ser still can't create the service.
Here's what I've tried:
- Give the user cmd.exe and sc.exe permissions (using CACLS).
- Use PsExec to run cmd (with -i -s) instead of cmd.exe directly.
- Using the SubInAcl command so the user has permissions to the both Windows Service. But here's the thing, at the time I don't have any Service, so it doesn't work.
Some remarkes:
- This Windows Services don't have any installer.
- The SC command is run using C# ProcessStartInfo.
- The SC command specifies the user and password of the Windows User that I've created.
- I really don't want the Windows Services to be run under a user account with Administrative Privileges.
I know that this thread is similar to some already here Auto-update a Windows Service, however I cannot find any working solution anywhere.
Sorry for the long text
I think your basic design is brittle and flawed. You should not be deleting and creating services as part of normal service operation.
What I would do would be to arrange that any service that needs updating in place was capable of doing it by itself. Basically put all the code that is subject to update in a DLL. The code in the service EXE is just a thin host in charge of loading the main DLL and invoking it's main processing loop. When the EXE determines that it is time to update it downloads the new DLL, presumably checking via a hash that it downloaded correctly. Next the processing loop is terminated, the old DLL is unloaded, the new DLL is loaded and the processing loop started again.
This approach is much less intrusive and avoids all permission and rights issues. You can write a single service host EXE and have multiple DLLs containing the logic.
精彩评论