|
The service controller is out of sync with the registry.
If you reboot, it will resync and work properly, but it sucks as a good solution.
As someone suggested below the 'right way is'
ConnectionOptions coOptions = new ConnectionOptions();
coOptions.Impersonation = ImpersonationLevel.Impersonate;
ManagementScope mgmtScope = new System.Management.ManagementScope(@"root\CIMV2", coOptions);
mgmtScope.Connect();
ManagementObject wmiService;
wmiService = new ManagementObject("Win32_Service.Name='" + ServiceMonitorInstaller.ServiceName + "'");
ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");
InParam["DesktopInteract"] = true;
ManagementBaseObject OutParam = wmiService.InvokeMethod("Change", InParam, null);
|
|
|
|
|
Thank you for posting this alternative solution. This worked for me.
|
|
|
|
|
You can start and stop your services using this code:
public static class ServiceHelper
{
public static void StartService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
var servicesDependedOn = service.ServicesDependedOn;
if (null != servicesDependedOn)
{
foreach (var svc in servicesDependedOn)
{
StartService(svc.ServiceName, timeoutMilliseconds);
}
}
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
service.Refresh();
}
catch
{
}
finally
{
service.Dispose();
}
}
public static void StopService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
var dependentServices = service.DependentServices;
if (null != dependentServices)
{
foreach (var svc in dependentServices)
{
StopService(svc.ServiceName, timeoutMilliseconds);
}
}
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Start();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
service.Refresh();
}
catch
{
}
finally
{
service.Dispose();
}
}
public static bool IsServiceAvailable(string serviceName)
{
var result = false;
ServiceController service = null;
try
{
service = new ServiceController(serviceName);
result = service.Status == ServiceControllerStatus.Running;
return result;
}
catch
{
return result;
}
finally
{
if (null != service)
{
service.Dispose();
}
}
}
}
|
|
|
|
|
The StopService method was wrong, i fixed that:
public static void StartService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
var servicesDependedOn = service.ServicesDependedOn;
if (null != servicesDependedOn)
{
foreach (var svc in servicesDependedOn)
{
StartService(svc.ServiceName, timeoutMilliseconds);
}
}
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
if (service.Status != ServiceControllerStatus.Running)
{
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
service.Refresh();
}
}
catch
{
}
finally
{
service.Dispose();
}
}
public static void StopService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
var dependentServices = service.DependentServices;
if (null != dependentServices)
{
foreach (var svc in dependentServices)
{
StopService(svc.ServiceName, timeoutMilliseconds);
}
}
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
if (service.Status != ServiceControllerStatus.Stopped)
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
service.Refresh();
}
}
catch
{
}
finally
{
service.Dispose();
}
}
public static bool IsServiceAvailable(string serviceName)
{
var result = false;
ServiceController service = null;
try
{
service = new ServiceController(serviceName);
result = service.Status == ServiceControllerStatus.Running;
return result;
}
catch
{
return result;
}
finally
{
if (null != service)
{
service.Dispose();
}
}
}
}
|
|
|
|
|
Hi all,
I'm trying to use this code, and i'm having a problem, i can't make it to work... i have read all posts.
I'm using this code on (ProjectInstaller.VB).
#Region " Component Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Component Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
'Add initialization code after the call to InitializeComponent
Dim si As New ServiceProcess.ServiceInstaller
si.ServiceName = "Myapp"
si.DisplayName = "Myapp"
si.StartType = ServiceProcess.ServiceStartMode.Manual
Me.Installers.Add(si)
Dim spi As New ServiceProcess.ServiceProcessInstaller
spi.Account = System.ServiceProcess.ServiceAccount.LocalSystem
spi.Password = Nothing
spi.Username = Nothing
Me.Installers.Add(spi)
Dim ckey As RegistryKey = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Services\Myapp", True)
If ckey.GetValue("Type") <> Nothing Then
ckey.SetValue("Type", (ckey.GetValue("Type") Or 256))
End If
End Sub
But wend i try to install my service i get this error.
"Unable to create an instance of the "Myapp".ProjectInstaller installer type. --> Exception has been throw by the target of an invocation. --> Object reference not set to an instance of an object."
After this error my installation will rollback.
Cold some one gives a help....
Reagards,
mpires
|
|
|
|
|
Tks, i have found the solution....
I have set on after install:
Dim ckey As RegistryKey = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Services\Myapp", True)
If ckey.GetValue("Type") <> Nothing Then
ckey.SetValue("Type", (ckey.GetValue("Type") Or 256))
End If
And it works....
Nice....
|
|
|
|
|
This is a really good article for how to do this in C#.
If, however, you're not using C#, and are using the Platform SDK,
you can simply specify the DesktopInteract mode in the CreateService() API call e.g.:
SC_HANDLE schService = CreateService(schSCManager,
"MyService",
"MyServiceDisplayName",
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
"\"MyQuotedFullPathToExe\"",
NULL, NULL, NULL, NULL, NULL);
Note that in order for the interact mode to function, the service must use the LocalSystem account (second to last parameter = NULL).
Also note that if you set the 'Type' registry value directly to 0x00000110 or similar, this will not work on Windows 2003 server, so the programmatic way is definitely the better bet.
Hope this helps!
|
|
|
|
|
hello All:
Can anyone please can convert the code to vb.net ?
Thanks in advance
Albert
|
|
|
|
|
Public Sub New()
InitializeComponent
Dim si As ServiceInstaller = New ServiceInstaller
si.ServiceName = "WindowsService1"
si.DisplayName = "WindowsService1"
si.StartType = ServiceStartMode.Manual
Me.Installers.Add(si)
Dim spi As ServiceProcessInstaller = New ServiceProcessInstaller
spi.Account = System.ServiceProcess.ServiceAccount.LocalSystem
spi.Password = Nothing
spi.Username = Nothing
Me.Installers.Add(spi)
Dim ckey As RegistryKey = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Services\WindowsService1", True)
If Not (ckey Is Nothing) Then
If Not (ckey.GetValue("Type") Is Nothing) Then
ckey.SetValue("Type", (CType(ckey.GetValue("Type"), Integer) Or 256))
End If
End If
End Sub
|
|
|
|
|
http://united-arab-emirates-airline.tangoing.info/
http://united-arab-emirates-airline.tangoing.info/
|
|
|
|
|
this.Installers.Clear(); //add by kali, it work well
ServiceInstaller si = new ServiceInstaller();
si.ServiceName = "MonAgent";
si.DisplayName = "MonAgent";
si.StartType = ServiceStartMode.Automatic ;
this.Installers.Add(si);
ServiceProcessInstaller spi = new ServiceProcessInstaller();
spi.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
spi.Password = null;
spi.Username = null;
this.Installers.Add(spi);
// Here is where we set the bit on the value in the registry.
// Grab the subkey to our service
RegistryKey ckey = Registry.LocalMachine.OpenSubKey(
@"SYSTEM\CurrentControlSet\Services\MonAgent", true);
// Good to always do error checking!
if(ckey != null)
{
// Ok now lets make sure the "Type" value is there,
//and then do our bitwise operation on it.
if(ckey.GetValue("Type") != null)
{
ckey.SetValue("Type", ((int)ckey.GetValue("Type") | 256));
}
}
|
|
|
|
|
See the thread "The right way to do it".
This worked for me. The method in the original post (registry edit) didn't work on my Windows Server 2003 system. Looking at the service properties in the SCM, everything looked fine (the "Allow service to interact with desktop" flag was set), and there were no exceptions thrown in the GUI code, it just wouldn't show anything on the desktop (forms, notify icon, etc.)
Using this method, all worked great.
Regards (and thanks),
Robb
|
|
|
|
|
hi,
i tried changing the Registry Key...but my service is not able to run a GUI Application...what is the mistake??.....it is LocalSystem Account and n the properties box , the Desktop Interaction is enabled...
i tried this code,
/***********************code starts here*************************/
Process proc= new Process();
proc.StartInfo.FileName="E:\\MyStarter.exe";
proc.Start();
/***********************code starts here*************************/
what is wrong in my code???
with regards,
C.C.Chakkaradeep
|
|
|
|
|
Hi,
By the way did you resolve this problem ? because I have the same problem ?
Thanks
Laurent
|
|
|
|
|
This is not working for the application. There is uncheck option available after putting this code.
If any one got the demo application plz post here.
Regards,
Lalit Narayan Dubey
S/W Developer,Noida
|
|
|
|
|
Hello Laurent,
I think this is not the proper solution. Because I felt one thing very interesting i have created on application ..
There this registry chnage us working fine the service is desktop interactive.
But in other application its failing to check the check box option. Event all the code is same.
So i think its better to find some thig good solution.
Regards,
Lalit Narayan Dubey
S/W Developer,Noida
|
|
|
|
|
Absolutely delightful! I had been looking for this piece of code or at least a direction towards doing it myself for sooo long, and finally got it. Though I was quite fine with the registry-'tampering' code, I impelemented it in VB.NET and though the checkbox was set to true for the service, it didn't quite work I wonder why??
Eventually I used the 'right-way-to-do-it' piece of code and seriously it works like a dream. And moreover I got aware of a whole new concept of altering a service's properties on the fly!
All in all, loved it!
|
|
|
|
|
I have a service that I install to run as the "NetworkService" user, instead of the "LocalSystem" user. I tried flipping that bit by hand in the registry and restarting the service, but my console window does not display, like it does when I run as LocalSystem. So I suspect that the bit (just like the dialog box checkbox) only applies if you are running as LocalSystem. Maybe not, but I though I would mention it.
|
|
|
|
|
So, is there any work around to enable "interact with desktop" for local user account?
|
|
|
|
|
Thank you guys: Robert for the initiative and knowledge, "Anonymous" for WMI suggestion and Richard for "the correct way" to get the thing done.
You don't need "Allow Interact with Desktop" for debugging with MessageBox.Show - ServiceNotification option works nicely.
Blake is right, of course, that interactive services are dangerous but
sometimes one needs a quick and dirty solution.
I really had to write a quick and dirty demo and Richard's suggestion to use ChangeServiceConfig was very helpful. It took a couple hours to declare and put in work the related P/Invoke functions (OpenSCManager, OpenService, ...) - the great PInvoke site (http://www.pinvoke.net) doesn't have them yet. Since I do the job on ProjectInstaller.Committed event I don't need to call LockServiceDatabase.
I'd like to attach here my class (about 150 lines, written carefully) but there is no place for attachments here, unfortunately.
Israel Shnaidman
|
|
|
|
|
I am interested in why this is dangerous. You say "Blake is right of course . . ." but I couldn't find a message from anyone called Blake, or anything about the dangers. Why is this dangerous? Why should it only be used for "quick and dirty". I am writing a "proper" application that will go on sale top the public. Should I not use this method? If not, what is the recommended alternative?
Dave
|
|
|
|
|
Hi Israel,
I am trying to load a form from OnStart method of windows service.
Plz help me by giving proper line of code or way to move.
Amit
|
|
|
|
|
Thank you,Thank you,Thank you,Thank you,Thank you,
Thank you,Thank you,Thank you,Thank you,Thank you,Thank you,Thank you,
Thank you,Thank you,Thank you,
Thank you,Thank you,Thank you,Thank you,
|
|
|
|
|
Thank you, thank you, thank you, thank you.
Thank you.
|
|
|
|
|
Thank you, thank you, thank you, thank you.
Thank you, thank you, thank you, thank you.
Thank you, thank you, thank you, thank you.
Thank you, thank you, thank you, thank you.
|
|
|
|
|