Stop/Start service in code in Windows 7 - c#

I am trying to write a app and service which monitor a given set of services and a) makes sure they are running and b) based on certain criteria, restart them as needed.
I keep running into an access denied error.
If I simply iterate through the processes on the system, find the one I want like so:
foreach (ServiceController sc in ServiceController.GetServices())
{
if(sc.ServiceName == "MyServiceName")
{
sc.Stop();
sc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 60));
sc.Start();
}
}
I get:
InnerException: System.InvalidOperationException
Message="Cannot open My Service service on computer '.'."
Source="System.ServiceProcess"
StackTrace:
at System.ServiceProcess.ServiceController.GetServiceHandle(Int32 desiredAccess)
at System.ServiceProcess.ServiceController.Stop()
at lib.ListServices() in D:\lib.cs:line 552
at lib.Init() in D:\lib.cs:line 56
InnerException: System.ComponentModel.Win32Exception
Message="Access is denied"
ErrorCode=-2147467259
NativeErrorCode=5
InnerException:
I have tried to impersonate a user, I have tried to do the same code from another service which is running as a system service. Neither of which have actually been able to affect the service. If its started, I cannot stop it. If its stopped, I cannot start it. I know this is all related to permissions I'm just not finding a mechanism that actually lets me control the service.
Any assistance would be greatly appreciated.

Diagnoses:
UAC is indeed the problem. Your application requires elevated user rights. That is why the "run as administrator" works outside of the IDE.
Some sites suggest disabling UAC. As this is not a possibility in my environment, I decided to request elevated user right via code. Wikipedia provided the help I needed. The "Requesting elevation" section provides the solution.
The solution in short:
Edit your application manifest file to reflect your requirement.
1.1. Right click your project
1.2. Click "Properties"
1.3. Select "Application" tab - default page
1.4. Click "View UAC Settings" - This button opens the application manifest file (app.manifest)
1.5. Look for the "UAC Manifest Options" section
1.6. Remove or comment the current entry - {requestedExecutionLevel level="asInvoker" uiAccess="false"}
1.7. Change to {requestedExecutionLevel level="requireAdministrator" uiAccess="false"}. MS provides your 3 options as part of the section comment.

I think this is UAC fault...
Try to run the exe with right click and "Run as Administrator".
If that helps, you might want to add a Manifest file to your executable project with level="requireAdministrator".

Could it be the .net security policy that is preventing your app from controlling the service?
According to MSDN, your assembly needs full trust for this to work.

You have to set the application to run as administrator. If you look under the files properties menu. On the compatibility tab, there is a Privilige Level option, to let the program run as administrator. It worked with my own system trays in windows 7.

Related

Windows, Start service System.InvalidOperationException: Cannot start service on computer '.' Access in Denied(Running as Admin)

I am trying to start service using the below code. This works fine for 99% machines but i get this issue on user machines. Any help to be able to reproduce this error or why this issue happens.
ServiceController sc = new ServiceController(name);
if (sc.Status == ServiceControllerStatus.Running ||
sc.Status == ServiceControllerStatus.StartPending)
{
sc.WaitForStatus(ServiceControllerStatus.Running);
Logger.Info("Service already running");
return true;
}
sc.Start();
Error I receive is
System.InvalidOperationException: Cannot start service on computer
'.'. ---> System.ComponentModel.Win32Exception: Access is denied
I am running with Administrator privileges
When creating the service I also run sc sdset command to make service start stop by non admin processes.
There is a whole thread about it in social msdn. The issue persisted for numerous users and it seems you do not have enough privileges to start the service, in which case you will have to change the service into Administrative account:
make sure that the service is set to Local Account by:
Rightclick on the property(in Services.msc panel).
select the Log on option
And then check again to see if it's working.
I am assuming you are trying to achieve a scenario similar to this, i.e., install a service and start it automatically.
Assuming you have made sure that you are really running as Administrator, i.e., the Admin command prompt or Run As Administrator.
Also, assuming you have restarted the machine to make sure that old version of your service is really removed, as you have tried multiple times to install / uninstall your service.
The error Access is denied essentially means that the user running it does not have access. Since you have said that you are running as Administrator, it is possibly that even Administrator does not have access to start the service. May be you are in a locked down environment (likely via Group Policy), where only the Domain Administrator is the "most powerful" !
The next step would be to investigate the permissions your service has. A useful tool for this is: SubInAcl
https://ss64.com/nt/subinacl.html
Display or modify Access Control Entries (ACEs) for file and folder Permissions, Ownership and Domain.
SubInAcl /service "your service name"
The above command is not easy to use ! You need to download it from the Microsoft web site.
Another useful tool is the SC command. This would normally be available by default.
Service Control - Create, Start, Stop, Query or Delete any Windows SERVICE.
SC sdshow "your service name"
would give details of the permission.
This would give you data which can help in further investigation.
You could also start / stop the service with this command. You can try with this to check whether you are getting the same exception when using this tool as well.
The following serverfault question gives some details about setting permission to a service
https://serverfault.com/questions/187302/how-do-i-grant-start-stop-restart-permissions-on-a-service-to-an-arbitrary-user
If you want to see the Stack trace from installutil you can use the /ShowcallStack option
https://learn.microsoft.com/en-us/dotnet/framework/tools/installutil-exe-installer-tool
/ShowCallStack
Outputs the call stack to the log file if an exception occurs at any point during installation.
This is not an answer, it is my further exploration of the question.
Here is the log
Running a transacted installation.
Beginning the Install phase of the installation.
See the contents of the log file for the
D:\devnet10\Flight\Flight.ServiceHost\bin\Debug\flight.servicehost.exe assembly's progress.
The file is located at D:\devnet10\Flight\Flight.ServiceHost\bin\Debug\flight.servicehost.InstallLog.
An exception occurred during the Install phase.
System.InvalidOperationException: An exception occurred in the OnAfterInstall event handler of Flight.ServiceHost.Installation.
at System.Configuration.Install.Installer.Install(IDictionary stateSaver)
at Flight.ServiceHost.Installation.Install(IDictionary stateSaver) in D:\devnet10\Flight\Flight.ServiceHost\Installation.cs:line 36
at System.Configuration.Install.Installer.Install(IDictionary stateSaver)
at System.Configuration.Install.AssemblyInstaller.Install(IDictionary savedState)
at System.Configuration.Install.Installer.Install(IDictionary stateSaver)
at System.Configuration.Install.TransactedInstaller.Install(IDictionary savedState)
The inner exception System.InvalidOperationException was thrown with the following error message: Cannot start service PreFlight on computer '.'..
at System.ServiceProcess.ServiceController.Start(String[] args)
at System.ServiceProcess.ServiceController.Start()
at Flight.ServiceHost.Installation.OnAfterInstall(IDictionary savedState) in D:\devnet10\Flight\Flight.ServiceHost\Installation.cs:line 49
at System.Configuration.Install.Installer.Install(IDictionary stateSaver)
The inner exception System.ComponentModel.Win32Exception was thrown with the following error message: Access is denied.
The Rollback phase of the installation is beginning.
See the contents of the log file for the D:\devnet10\Flight\Flight.ServiceHost\bin\Debug\flight.servicehost.exe assembly's progress.
The file is located at D:\devnet10\Flight\Flight.ServiceHost\bin\Debug\flight.servicehost.InstallLog.
The Rollback phase completed successfully.
The transacted install has completed.
[Update]
I should mention that I am running WIndows 10
I managed to create an installer using an installer project, which does work.
The issue by me was RunningAsLocalService in topshelf, hope this helps someone.

Cannot Start Windows Service in NetworkService account

I have a windows service project implementation that I am trying to install as network service.
process = new ServiceProcessInstaller();
process.Account = ServiceAccount.NetworkService;
however whenever I try to start the service I get :
System error 5 has occurred.
Access is denied.
This comes after running the net start MyService command in the visual studio command prompt which is running as administrator by the way.
Any help on how to get this to work? Thanks.
I would check that the Network Service account has permissions to execute. Steps to check:
In Windows explorer go to the folder containing the binaries of the service
Right-click on the folder > Properties > Security tab > Edit button
Add > "NETWORK SERVICE" > OK
Give it full control (just to test and then reduce permissions till it working)
Your Net Start MyService is probably not running with escalated privileges. Your command requires (I believe) Administrative Privileges.
Update
Not sure why, but your privileges on your service are weird. By default privileges of services should look like:
D:(A;CI;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)
ACE Type: ACCESS_ALLOWED_ACE_TYPE
Trustee: NT AUTHORITY\SYSTEM
AccessMask:
ADS_RIGHT_DELETE
ADS_RIGHT_READ_CONTROL
ADS_RIGHT_WRITE_DAC
ADS_RIGHT_WRITE_OWNER
ADS_RIGHT_DS_CREATE_CHILD
ADS_RIGHT_DS_DELETE_CHILD
ADS_RIGHT_ACTRL_DS_LIST
ADS_RIGHT_DS_SELF
ADS_RIGHT_DS_READ_PROP
ADS_RIGHT_DS_WRITE_PROP
ADS_RIGHT_DS_DELETE_TREE
ADS_RIGHT_DS_LIST_OBJECT
ADS_RIGHT_DS_CONTROL_ACCESS
However your's looks like:
D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)
ACE Type: ACCESS_ALLOWED_ACE_TYPE
Trustee: NT AUTHORITY\SYSTEM
AccessMask:
ADS_RIGHT_READ_CONTROL
ADS_RIGHT_DS_CREATE_CHILD
ADS_RIGHT_ACTRL_DS_LIST
ADS_RIGHT_DS_SELF
ADS_RIGHT_DS_READ_PROP
ADS_RIGHT_DS_WRITE_PROP
ADS_RIGHT_DS_DELETE_TREE
ADS_RIGHT_DS_LIST_OBJECT
ADS_RIGHT_DS_CONTROL_ACCESS
I'm not sure exactly how that came to be. Try uninstalling and reinstalling?
You can download SddlParse (google it :) to parse out the Security Descriptor Definition Language.
The "Access denied" message applies to the user trying to start the service, not the account in which the service is run.
Can you start the service from:
the Services Control Panel applet?
an elevated command prompt you started yourself (not from Visual Studio)?

Installing C# Windows Service on Windows 7

I have a batch file that I have been using to install my C# Windows Services for awhile now, never had a problem until Windows 7. I have attempted to run the batch file with Administrator privileges. I have attempted to run the command prompt with admin privs, navigate to the windows service EXE and run InstallUtil there. Still doesn't work.
After reading some other suggestions I tried moving my files out of the /bin folder and running them from another location but that also didn't work.
The batch file looks like this
#ECHO OFF
REM The following directory is for .NET 2.0
set DOTNETFX2=%SystemRoot%\Microsoft.NET\Framework\v2.0.50727
set PATH=%PATH%;%DOTNETFX2%
echo Installing IEPPAMS Win Service...
echo ---------------------------------------------------
InstallUtil /i IEPPAMS_WinService1.exe
echo ---------------------------------------------------
echo Done.
and I have a install log file that I dump info to. If I just double click the .bat file I get
Running a transacted installation.
Beginning the Install phase of the
installation. See the contents of the
log file for the
C:\Users\Justin\Desktop\service
test\IEPPAMS_WinService1.exe
assembly's progress. The file is
located at
C:\Users\Justin\Desktop\service
test\IEPPAMS_WinService1.InstallLog.
An exception occurred during the
Install phase.
System.InvalidOperationException:
Cannot open Service Control Manager on
computer '.'. This operation might
require other privileges. The inner
exception
System.ComponentModel.Win32Exception
was thrown with the following error
message: Access is denied.
The Rollback phase of the installation
is beginning. See the contents of the
log file for the
C:\Users\Justin\Desktop\service
test\IEPPAMS_WinService1.exe
assembly's progress. The file is
located at
C:\Users\Justin\Desktop\service
test\IEPPAMS_WinService1.InstallLog.
The Rollback phase completed
successfully.
The transacted install has completed.
When I run the .bat file with admin privileges nothing is written to the log file, and the service is still not installed.
Any thoughts? Is there a new way to install services in Windows 7?
Right click on the batch file and run it as Administrator.
You are most likely running into battle with the new security model (User Account Control) from Windows Vista and Windows 7. Even if you are running as an account that has Admin rights you will still need to elevate to do some (most) administrative activities. (Yes it is possible to disable this feature, but don't)
UAC (MSDN)
UAC (Wikipedia)
InstallUtil (MSDN)
Edit... The correct commandline is InstallUtil YourApp.exe. The /i does not look to be a vaild switch for InstallUtil.
So I was able to fix the problem by typing in the command line the entire path to InstallUtil and it worked. So after navigating to the folder that had my EXE I typed the following:
C:\Windows\Microsoft.NET\Framework\v4.0.21006\installutil.exe
IEPPAMS_WinService1.exe
Not sure why I have to do that in Windows 7 now when I never had to in XP, but oh well. Thanks for all the suggestions!
When I run the .bat file with admin privileges nothing is written to the log file, and the service is still not installed.
First off, you HAVE to run as admin permissions.
Second, when you "Run as Administrator", it actually changes the directory to c:\windows\system32 as the initial directory ( no idea why ), which would probably explain why running as admin causes no log file. Manually change to the path IEPPAMS_WinService1.exe resides in that the start of your script.

Mark MSI so it has to be run as elevated Administrator account

I have a CustomAction as part of an MSI.
It MUST run as a domain account that is also a member of the local Administrators account.
It can't use the NoImpersonate flag to run the custom action as NT Authority\System as it will not then get access to network resources.
On Vista/2008 with UAC enabled if NoImpersonate is off then it will run as the executing user but with the unprivileged token and not get access to local resources such as .installState. See UAC Architecture
Anyone know of a way to either
Force the MSI to run with the elevated token in the same way that running from an elevated command prompt does?
Force the CustomAction to run elevated (requireAdministrator in manifest doesn't appear to work)?
Work out if UAC is enabled and if it hasn't been ran elevated and if so warn or cancel the installation?
Answering my own question for any other poor s0d looking at this.
You can't add a manifest to an MSI. You could add a SETUP.EXE or bootstrapper to shell the MSI and manifest that with requireAdministrator but that defeats some of the point of using an MSI.
Adding a manifest to a CustomAction does not work as it is ran from msiexec.exe
The way I have tackled this is to set the MSIUSEREALADMINDETECTION property to 1 so the Privileged condition actually works and add a Launch Condition for Privileged that gives an error message about running via an elevated command prompt and then quits the installation.
This has the happy side effect - when an msi is ran from an elevated command prompt deferred CustomActions are ran as the current user with a full Administrator token (rather than standard user token) regardless of the NoImpersonate setting.
More details - http://www.microsoft.com/downloads/details.aspx?FamilyID=2cd92e43-6cda-478a-9e3b-4f831e899433
[Edit] - I've put script here that lets you add the MSIUSEREALADMINDETECTION property as VS doesn't have ability to do it and Orca's a pain.
requireAdministrator in the manifest should work.
You can also use a bootloader .exe file which can use ShellExecute with "RUNAS" as the verb (you can use 7-zip to create the bootloader, or there are many other ways).
You can creating a simple sfx archive file for msi file with Winrar and these options:
Setup tab > Run after execution input: your msi file name
Advanced tab > Mark Request Administrative access option checkbox

Uninstall Command Fails Only in Release Mode

I'm able to successfully uninstall a third-party application via the command line and via a custom Inno Setup installer.
Command line Execution:
MSIEXEC.exe /x {14D74337-01C2-4F8F-B44B-67FC613E5B1F} /qn
Inno Setup Command:
[Run]
Filename: msiexec.exe; Flags: runhidden waituntilterminated;
Parameters: "/x {{14D74337-01C2-4F8F-B44B-67FC613E5B1F} /qn";
StatusMsg: "Uninstalling Service...";
I am also able to uninstall the application programmatically when executing the following C# code in debug mode.
C# Code:
string fileName = "MSIEXEC.exe";
string arguments = "/x {14D74337-01C2-4F8F-B44B-67FC613E5B1F} /qn";
ProcessStartInfo psi = new ProcessStartInfo(fileName, arguments)
{
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true
};
Process process = Process.Start(psi);
string errorMsg = process.StandardOutput.ReadToEnd();
process.WaitForExit();
The same C# code, however, produces the following failure output when run as a compiled, deployed Windows Service:
"This action is only valid for products that are currently installed."
Additional Comments:
The Windows Service which is issuing
the uninstall command is running on
the same machine as the code being
tested in Debug Mode. The Windows
Service is running/logged on as the
Local system account.
I have consulted my application logs
and I have validated that the
executed command arguments are thhe
same in both debug and release mode.
I have consulted the Event Viewer
but it doesn't offer any clues.
Thoughts? Any help would be greatly appreciated. Thanks.
Step 1: Check the MSI error log files
I'm suspicious that your problem is due to running as LocalSystem.
The Local System account is not the same as a normal user account which happens to have admin rights. It has no access to the network, and its interaction with the registry and file system is quite different.
From memory any requests to read/write to your 'home directory' or HKCU under the registry actually go into either the default user profile, or in the case of temp dirs, c:\windows\temp
I've come across similar problems in the past with installation, a customer was using the SYSTEM account to install and this was causing all sorts of permission problems for non-administrative users.
MSI log files aren't really going to help if the application doesn't appear "installed", I'd suggest starting with capturing the output of MSIINV.EXE under the system account, that will get you an "Inventory" of the currently installed programs (or what that user sees installed) http://blogs.msdn.com/brada/archive/2005/06/24/432209.aspx
I think you probably need to go back to the drawing board and see if you really need the windows service to do the uninstall. You'll probably come across all sorts of Vista UAC issues if you haven't already...
Thanks to those offering help. This appears to be a permissions issue. I have updated my service to run under an Administrator account and it was able to successfully uninstall the third-party application. To Orion's point, though the Local System account is a powerful account that has full access to the system -- http://technet.microsoft.com/en-us/library/cc782435.aspx -- it doesn't seem to have the necessary rights to perform the uninstall.
[See additional comments for full story regarding the LocalSystem being able to uninstall application for which it installed.]
This is bizarre. LocalSystem definitely has the privileges to install applications (that's how Windows Update and software deployment in Active Directory work), so it should be able to uninstall as well.
Perhaps the application is initially installed per-user instead of per-machine?
#Paul Lalonde
The app's installer is wrapped within a custom InnoSetup Installer. The InnoSetup installer, in turn, is manually executed by the logged in user. That said, the uninstall is trigged by a service running under the Local System account.
Apparently, you were on to something. I put together a quick test which had the service running under the LocalSystem account install as well as uninstall the application and everything worked flawlessly. You were correct. The LocalSystem account has required uninstall permissions for applications in which it installs. You saved the day. Thanks for the feedback!

Categories

Resources