Windows 7 Trigger start

Trips

Well-known member
Joined
Aug 7, 2010
Messages
2,788
I have a Windows service in a Visual Studio .NET project (C#) that I want to start from elsewhere in the project . When I try and use the following code
ServiceController service = new ServiceController("servicename");

<pre>ServiceController service = new ServiceController("servicename");
service.Start();[/code]

I get an exception
<!-- [if gte mso 10]> <mce:style>
<span style="font-size:8pt; font-family:"Courier New" A first chance exception of type System.InvalidOperationException occurred in System.ServiceProcess.dll
<span style="font-size:8pt; font-family:"Courier New" Cannot open servicename service on computer ..
This is to with User Access Control in Windows 7. I have tried lots of things to start it but they dont work so my only option is to change the design of the service so it can be started (I did not write the service).
I have seen a code example called CSWin7TriggerStartService that shows how to make a service start when the IP address on the PC that is running it changes or when someone inserts a USB stick.
It uses a function called ChangeServiceConfig2 that allows the configuration of the service being cretaed to start when certain events occur (eg IP address changing).

There is class in it called ServiceNative.cs (see below)

<div style="color:Black;background-color:White; <pre>
<span style="color:Green; /****************************** Module Header ******************************
* Module Name: ServiceNative.cs
* Project: CSWin7TriggerStartService
* Copyright (c) Microsoft Corporation.
*
* The P/Invoke signatures of native service APIs and structs.
*
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
* All other rights reserved.
*
* History:
* * 8/1/2009 4:50 AM Jialiang Ge Created
***************************************************************************/

<span style="color:Blue; #region Using directives
<span style="color:Blue; using System;
<span style="color:Blue; using System.Collections.Generic;
<span style="color:Blue; using System.Linq;
<span style="color:Blue; using System.Text;
<span style="color:Blue; using System.Runtime.InteropServices;
<span style="color:Blue; #endregion


[Flags]
<span style="color:Blue; public <span style="color:Blue; enum ServiceControlAccessRights : <span style="color:Blue; int
{
<span style="color:Green; // Required to connect to the service control manager.
SC_MANAGER_CONNECT = 0x0001,

<span style="color:Green; // Required to call the CreateService function to create a service
<span style="color:Green; // object and add it to the database.
SC_MANAGER_CREATE_SERVICE = 0x0002,

<span style="color:Green; // Required to call the EnumServicesStatusEx function to list the
<span style="color:Green; // services that are in the database.
SC_MANAGER_ENUMERATE_SERVICE = 0x0004,

<span style="color:Green; // Required to call the LockServiceDatabase function to acquire a lock on
<span style="color:Green; // the database.
SC_MANAGER_LOCK = 0x0008,

<span style="color:Green; // Required to call the QueryServiceLockStatus function to retrieve the
<span style="color:Green; // lock status information for the database
SC_MANAGER_QUERY_LOCK_STATUS = 0x0010,

<span style="color:Green; // Required to call the NotifyBootConfigStatus function.
SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020,

<span style="color:Green; // Includes STANDARD_RIGHTS_REQUIRED, in addition to all access rights in
<span style="color:Green; // this table.
SC_MANAGER_ALL_ACCESS = 0xF003F
}


[Flags]
<span style="color:Blue; public <span style="color:Blue; enum ServiceAccessRights : <span style="color:Blue; int
{
<span style="color:Green; // Required to call the QueryServiceConfig and QueryServiceConfig2
<span style="color:Green; // functions to query the service configuration.
SERVICE_QUERY_CONFIG = 0x0001,

<span style="color:Green; // Required to call the ChangeServiceConfig or ChangeServiceConfig2
<span style="color:Green; // function to change the service configuration. Because this grants the
<span style="color:Green; // caller the right to change the executable file that the system runs,
<span style="color:Green; // it should be granted only to administrators.
SERVICE_CHANGE_CONFIG = 0x0002,

<span style="color:Green; // Required to call the QueryServiceStatusEx function to ask the service
<span style="color:Green; // control manager about the status of the service.
SERVICE_QUERY_STATUS = 0x0004,

<span style="color:Green; // Required to call the EnumDependentServices function to enumerate all
<span style="color:Green; // the services dependent on the service.
SERVICE_ENUMERATE_DEPENDENTS = 0x0008,

<span style="color:Green; // Required to call the StartService function to start the service.
SERVICE_START = 0x0010,

<span style="color:Green; // Required to call the ControlService function to stop the service.
SERVICE_STOP = 0x0020,

<span style="color:Green; // Required to call the ControlService function to pause or continue the
<span style="color:Green; // service.
SERVICE_PAUSE_CONTINUE = 0x0040,

<span style="color:Green; // Required to call the ControlService function to ask the service to
<span style="color:Green; // report its status immediately.
SERVICE_INTERROGATE = 0x0080,

<span style="color:Green; // Required to call the ControlService function to specify a user-defined
<span style="color:Green; // control code.
SERVICE_USER_DEFINED_CONTROL = 0x0100,

<span style="color:Green; // Includes STANDARD_RIGHTS_REQUIRED in addition to all access rights in
<span style="color:Green; // this table.
SERVICE_ALL_ACCESS = 0xF01FF
}


<span style="color:Blue; public <span style="color:Blue; enum ServiceConfig2InfoLevel : <span style="color:Blue; uint
{
SERVICE_CONFIG_DESCRIPTION = 0x00000001,
SERVICE_CONFIG_FAILURE_ACTIONS = 0x00000002,
SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 0x00000003,
SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 0x00000004,
SERVICE_CONFIG_SERVICE_SID_INFO = 0x00000005,
SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 0x00000006,
SERVICE_CONFIG_PRESHUTDOWN_INFO = 0x00000007,
SERVICE_CONFIG_TRIGGER_INFO = 0x00000008,
SERVICE_CONFIG_PREFERRED_NODE = 0x00000009
}


<span style="color:Blue; public <span style="color:Blue; enum ServiceTriggerType : <span style="color:Blue; uint
{
<span style="color:Green; // The event is triggered when a device of the specified device interface
<span style="color:Green; // class arrives or is present when the system starts. This trigger event
<span style="color:Green; // is commonly used to start a service.
SERVICE_TRIGGER_TYPE_DEVICE_INTERFACE_ARRIVAL = 1,

<span style="color:Green; // The event is triggered when the first IP address on the TCP/IP
<span style="color:Green; // networking stack becomes available or the last IP address on the stack
<span style="color:Green; // becomes unavailable. This trigger event can be used to start or stop a
<span style="color:Green; // service.
SERVICE_TRIGGER_TYPE_IP_ADDRESS_AVAILABILITY = 2,

<span style="color:Green; // The event is triggered when the computer joins or leaves a domain.
<span style="color:Green; // This trigger event can be used to start or stop a service.
SERVICE_TRIGGER_TYPE_DOMAIN_JOIN = 3,

<span style="color:Green; // The event is triggered when a firewall port is opened or approximately
<span style="color:Green; // 60 seconds after the firewall port is closed. This trigger event can
<span style="color:Green; // be used to start or stop a service.
SERVICE_TRIGGER_TYPE_FIREWALL_PORT_EVENT = 4,

<span style="color:Green; // The event is triggered when a machine policy or user policy change
<span style="color:Green; // occurs. This trigger event is commonly used to start a service.
SERVICE_TRIGGER_TYPE_GROUP_POLICY = 5,

<span style="color:Green; // The event is a custom event generated by an Event Tracing for Windows
<span style="color:Green; // (ETW) provider. This trigger event can be used to start or stop a
<span style="color:Green; // service.
SERVICE_TRIGGER_TYPE_CUSTOM = 20
}


<span style="color:Blue; public <span style="color:Blue; enum ServiceTriggerAction : <span style="color:Blue; uint
{
<span style="color:Green; // Start the service when the specified trigger event occurs.
SERVICE_TRIGGER_ACTION_SERVICE_START = 1,

<span style="color:Green; // Stop the service when the specified trigger event occurs.
SERVICE_TRIGGER_ACTION_SERVICE_STOP = 2
}


<span style="color:Blue; public <span style="color:Blue; enum ServiceTriggerDataType : <span style="color:Blue; uint
{
<span style="color:Green; // The trigger-specific data is in binary format.
SERVICE_TRIGGER_DATA_TYPE_BINARY = 1,

<span style="color:Green; // The trigger-specific data is in string format.
SERVICE_TRIGGER_DATA_TYPE_STRING = 2
}


[StructLayout(LayoutKind.Sequential)]
<span style="color:Blue; public <span style="color:Blue; struct SERVICE_TRIGGER_SPECIFIC_DATA_ITEM
{
<span style="color:Gray; ///<span style="color:Green; The data type of the trigger-specific data pointed to by pData.
<span style="color:Blue; public ServiceTriggerDataType dwDataType;

<span style="color:Gray; ///<span style="color:Green; The size of the trigger-specific data pointed to pData, in bytes.
<span style="color:Gray; ///<span style="color:Green; The maximum value is 1024.
<span style="color:Blue; public <span style="color:Blue; uint cbData;

<span style="color:Gray; ///<span style="color:Green; A pointer to the trigger-specific data for the service trigger event.
<span style="color:Gray; ///<span style="color:Green; Strings must be Unicode; ANSI strings are not supported.
<span style="color:Blue; public System.IntPtr pData;
}


[StructLayout(LayoutKind.Sequential)]
<span style="color:Blue; public <span style="color:Blue; struct SERVICE_TRIGGER
{
<span style="color:Gray; ///<span style="color:Green; The trigger event type.
<span style="color:Blue; public ServiceTriggerType dwTriggerType;

<span style="color:Gray; ///<span style="color:Green; The action to take when the specified trigger event occurs.
<span style="color:Blue; public ServiceTriggerAction dwAction;

<span style="color:Gray; ///<span style="color:Green; Points to a GUID that identifies the trigger event subtype. The value
<span style="color:Gray; ///<span style="color:Green; of this member depends on the value of the dwTriggerType member.
<span style="color:Blue; public IntPtr pTriggerSubtype;

<span style="color:Gray; ///<span style="color:Green; The number of SERVICE_TRIGGER_SPECIFIC_DATA_ITEM structures in the
<span style="color:Gray; ///<span style="color:Green; array pointed to by pDataItems.
<span style="color:Blue; public <span style="color:Blue; uint cDataItems;

<span style="color:Gray; ///<span style="color:Green; A pointer to an array of SERVICE_TRIGGER_SPECIFIC_DATA_ITEM
<span style="color:Gray; ///<span style="color:Green; structures that contain trigger-specific data.
<span style="color:Blue; public IntPtr pDataItems;
}


[StructLayout(LayoutKind.Sequential)]
<span style="color:Blue; public <span style="color:Blue; struct SERVICE_TRIGGER_INFO
{
<span style="color:Gray; ///<span style="color:Green; The number of triggers in the array of SERVICE_TRIGGER structures
<span style="color:Gray; ///<span style="color:Green; pointed to by the pTriggers member.
<span style="color:Blue; public <span style="color:Blue; uint cTriggers;

<span style="color:Gray; ///<span style="color:Green; A pointer to an array of SERVICE_TRIGGER structures that specify the
<span style="color:Gray; ///<span style="color:Green; trigger events for the service.
<span style="color:Blue; public IntPtr pTriggers;

<span style="color:Gray; ///<span style="color:Green; This member is reserved and must be NULL.
<span style="color:Blue; public IntPtr pReserved;
}


<span style="color:Blue; class ServiceNative
{
<span style="color:Gray; /// <span style="color:Gray; <summary>
<span style="color:Gray; ///<span style="color:Green; Establishes a connection to the service control manager on the
<span style="color:Gray; ///<span style="color:Green; specified computer and opens the specified service control manager
<span style="color:Gray; ///<span style="color:Green; database.
<span style="color:Gray; /// <span style="color:Gray; </summary>
<span style="color:Gray; /// <span style="color:Gray; <param name="machineName <span style="color:Green; Name of the target computer.</param>
<span style="color:Gray; /// <span style="color:Gray; <param name="databaseName
<span style="color:Gray; ///<span style="color:Green; Name of the service control manager database.
<span style="color:Gray; /// <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <param name="dwAccess
<span style="color:Gray; ///<span style="color:Green; The access to the service control manager.
<span style="color:Gray; /// <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <returns>
<span style="color:Gray; ///<span style="color:Green; If the function succeeds, the return value is a handle to the
<span style="color:Gray; ///<span style="color:Green; specified service control manager database. If the function fails,
<span style="color:Gray; ///<span style="color:Green; the return value is NULL. To get extended error information, call
<span style="color:Gray; ///<span style="color:Green; GetLastError.
<span style="color:Gray; /// <span style="color:Gray; </returns>
[DllImport(<span style="color:#A31515; "advapi32.dll", CharSet = CharSet.Auto, SetLastError = <span style="color:Blue; true)]
<span style="color:Blue; public <span style="color:Blue; static <span style="color:Blue; extern IntPtr OpenSCManager(<span style="color:Blue; string machineName,
<span style="color:Blue; string databaseName, ServiceControlAccessRights dwAccess);


<span style="color:Gray; /// <span style="color:Gray; <summary>
<span style="color:Gray; ///<span style="color:Green; Opens an existing service.
<span style="color:Gray; /// <span style="color:Gray; </summary>
<span style="color:Gray; /// <span style="color:Gray; <param name="hSCManager
<span style="color:Gray; ///<span style="color:Green; A handle to the service control manager database. The OpenSCManager
<span style="color:Gray; ///<span style="color:Green; function returns this handle.
<span style="color:Gray; /// <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <param name="lpServiceName
<span style="color:Gray; ///<span style="color:Green; The name of the service to be opened.
<span style="color:Gray; /// <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <param name="dwDesiredAccess <span style="color:Green; The access to the service.</param>
<span style="color:Gray; /// <span style="color:Gray; <returns><span style="color:Gray; </returns>
[DllImport(<span style="color:#A31515; "advapi32.dll", CharSet = CharSet.Auto, SetLastError = <span style="color:Blue; true)]
<span style="color:Blue; static <span style="color:Blue; extern IntPtr OpenService(IntPtr hSCManager,
<span style="color:Blue; string lpServiceName, <span style="color:Blue; uint dwDesiredAccess);


<span style="color:Gray; /// <span style="color:Gray; <summary>
<span style="color:Gray; ///<span style="color:Green; Changes the optional configuration parameters of a service.
<span style="color:Gray; /// <span style="color:Gray; </summary>
<span style="color:Gray; /// <span style="color:Gray; <param name="hService <span style="color:Green; A handle to the service.</param>
<span style="color:Gray; /// <span style="color:Gray; <param name="dwInfoLevel
<span style="color:Gray; ///<span style="color:Green; The configuration information to be changed.
<span style="color:Gray; /// <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <param name="lpInfo <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <returns><span style="color:Gray; </returns>
[DllImport(<span style="color:#A31515; "advapi32.dll", CharSet = CharSet.Auto, SetLastError = <span style="color:Blue; true)]
[<span style="color:Blue; return: MarshalAs(UnmanagedType.Bool)]
<span style="color:Blue; public <span style="color:Blue; static <span style="color:Blue; extern <span style="color:Blue; bool ChangeServiceConfig2(IntPtr hService,
ServiceConfig2InfoLevel dwInfoLevel, IntPtr lpInfo);


<span style="color:Gray; /// <span style="color:Gray; <summary>
<span style="color:Gray; ///<span style="color:Green; Retrieves the optional configuration parameters of the specified
<span style="color:Gray; ///<span style="color:Green; service.
<span style="color:Gray; /// <span style="color:Gray; </summary>
<span style="color:Gray; /// <span style="color:Gray; <param name="hService <span style="color:Green; A handle to the service.</param>
<span style="color:Gray; /// <span style="color:Gray; <param name="dwInfoLevel
<span style="color:Gray; ///<span style="color:Green; The configuration information to be queried.
<span style="color:Gray; /// <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <param name="lpBuffer
<span style="color:Gray; ///<span style="color:Green; A pointer to the buffer that receives the service configuration
<span style="color:Gray; ///<span style="color:Green; information.
<span style="color:Gray; /// <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <param name="cbBufSize
<span style="color:Gray; ///<span style="color:Green; The size of the structure pointed to by the lpBuffer parameter, in
<span style="color:Gray; ///<span style="color:Green; bytes.
<span style="color:Gray; /// <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <param name="pcbBytesNeeded
<span style="color:Gray; ///<span style="color:Green; A pointer to a variable that receives the number of bytes required to
<span style="color:Gray; ///<span style="color:Green; store the configuration information, if the function fails with
<span style="color:Gray; ///<span style="color:Green; ERROR_INSUFFICIENT_BUFFER.
<span style="color:Gray; /// <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <returns>
<span style="color:Gray; ///<span style="color:Green; If the function succeeds, the return value is nonzero. If the
<span style="color:Gray; ///<span style="color:Green; function fails, the return value is zero. To get extended error
<span style="color:Gray; ///<span style="color:Green; information, call GetLastError.
<span style="color:Gray; /// <span style="color:Gray; </returns>
[DllImport(<span style="color:#A31515; "advapi32.dll", CharSet = CharSet.Auto, SetLastError = <span style="color:Blue; true)]
<span style="color:Blue; public <span style="color:Blue; static <span style="color:Blue; extern <span style="color:Blue; int QueryServiceConfig2(IntPtr hService,
ServiceConfig2InfoLevel dwInfoLevel, IntPtr lpBuffer, <span style="color:Blue; int cbBufSize,
<span style="color:Blue; out <span style="color:Blue; int pcbBytesNeeded);


<span style="color:Gray; /// <span style="color:Gray; <summary>
<span style="color:Gray; ///<span style="color:Green; Closes a handle to a service control manager or service object.
<span style="color:Gray; /// <span style="color:Gray; </summary>
<span style="color:Gray; /// <span style="color:Gray; <param name="hSCObject
<span style="color:Gray; ///<span style="color:Green; A handle to the service control manager object or the service object
<span style="color:Gray; ///<span style="color:Green; to close.
<span style="color:Gray; /// <span style="color:Gray; </param>
<span style="color:Gray; /// <span style="color:Gray; <returns><span style="color:Gray; </returns>
[DllImport(<span style="color:#A31515; "advapi32.dll", EntryPoint = <span style="color:#A31515; "CloseServiceHandle")]
<span style="color:Blue; public <span style="color:Blue; static <span style="color:Blue; extern <span style="color:Blue; int CloseServiceHandle(IntPtr hSCObject);
}
[/code]

I have little experience of Windows 7 Trigger start events, can anyone tell me how to change the above class to trigger the service to start when the user logs off? I understand how it works to some extent. (The Service calls
ServiceNative.QueryServiceConfig2() from its OnStart() ) but I am stuck from there.

View the full article
 
Back
Top