Author | Message | Time |
---|---|---|
Mephisto | Is there a way to invoke the Win32 with the .NET framework (specifically C#). I'm trying to create an online method of starting and stopping a service. Normally to start a service I'd use a Win32 API call to StartService(), but obviously you can't just do that in C# (or I don't know how), so could someone explain to me how I'd do this? Or if this isn't possible (and even if it is please tell me anyways) is there a way to start a service and stop a service native to .NET? (btw, forgive me if there've been posts on this already, if so just direct me to them) | December 24, 2004, 3:08 AM |
kamakazie | http://www.google.com/search?hl=en&q=StartService+C%23+.NET&btnG=Google+Search Edit: You may also want to look at the System.ServiceProcess namespace on MSDN. | December 24, 2004, 3:23 AM |
Myndfyr | If you wanted to go entirely P/Invoke: Here is the prototype for CreateService: [code] SC_HANDLE CreateService( SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPCTSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCTSTR lpBinaryPathName, LPCTSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCTSTR lpDependencies, LPCTSTR lpServiceStartName, LPCTSTR lpPassword ); [/code] C# import: [code] [DllImport("advapi32.dll")] public static extern IntPtr CreateService( IntPtr hSCManager, string lpServiceName, string lpDisplayName, int dwDesiredAccess, int dwServiceType, int dwStartType, int dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, [Out] out int lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword ); [/code] This is the declaration for the dwAccessRights param: [code] #define SERVICE_QUERY_CONFIG 0x0001 #define SERVICE_CHANGE_CONFIG 0x0002 #define SERVICE_QUERY_STATUS 0x0004 #define SERVICE_ENUMERATE_DEPENDENTS 0x0008 #define SERVICE_START 0x0010 #define SERVICE_STOP 0x0020 #define SERVICE_PAUSE_CONTINUE 0x0040 #define SERVICE_INTERROGATE 0x0080 #define SERVICE_USER_DEFINED_CONTROL 0x0100 #define SERVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \ SERVICE_QUERY_CONFIG | \ SERVICE_CHANGE_CONFIG | \ SERVICE_QUERY_STATUS | \ SERVICE_ENUMERATE_DEPENDENTS | \ SERVICE_START | \ SERVICE_STOP | \ SERVICE_PAUSE_CONTINUE | \ SERVICE_INTERROGATE | \ SERVICE_USER_DEFINED_CONTROL) [/code] I'm not going to change that over to an enum. I do one for you below, you should be able to figure it out. To get the IntPtr hSCManager, you need to call OpenSCManager. C Prototype: [code] SC_HANDLE OpenSCManager( LPCTSTR lpMachineName, LPCTSTR lpDatabaseName, DWORD dwDesiredAccess ); [/code] C# equiv: [code] [DllImport("advapi32.dll")] public static extern IntPtr OpenSCManager( string lpMachineName, string lpDatabaseName, SvcCtrlManagerPrivilegeFlags dwDesiredAccess ); [/code] Also, you'll want to have the right access parameters. From WinSvc.h: [code] #define SC_MANAGER_CONNECT 0x0001 #define SC_MANAGER_CREATE_SERVICE 0x0002 #define SC_MANAGER_ENUMERATE_SERVICE 0x0004 #define SC_MANAGER_LOCK 0x0008 #define SC_MANAGER_QUERY_LOCK_STATUS 0x0010 #define SC_MANAGER_MODIFY_BOOT_CONFIG 0x0020 [/code] C#: [code] [Flags] public enum SvcCtrlManagerPrivilegeFlags { SC_MANAGER_CONNECT = 0x0001 SC_MANAGER_CREATE_SERVICE = 0x0002 SC_MANAGER_ENUMERATE_SERVICE = 0x0004 SC_MANAGER_LOCK = 0x0008 SC_MANAGER_QUERY_LOCK_STATUS = 0x0010 SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020 } [/code] Then you want to start the service. C prototype: [code] BOOL StartService( SC_HANDLE hService, DWORD dwNumServiceArgs, LPCTSTR* lpServiceArgVectors ); [/code] C# equivalent: [code] [DllImport("advapi32.dll")] public static extern bool StartService( IntPtr hService, int dwNumServiceArgs, [MarshalAs(UnmanagedType.LPArray)] string[] lpServiceArgVectors ); [/code] So in total, with the above declarations, you'd want to do: [code] IntPtr hSCM = OpenSCManager(null, null, SvcCtrlManagerPrivilegeFlags.SC_MANAGER_CREATE_SERVICE); IntPtr hSvc = CreateService(hSCM, "My Service", "My Service", AccessRightFlags.SERVICE_ALL_ACCESS, ServiceTypes.SERVICE_KERNEL_DRIVER, StartTypes.SERVICE_BOOT_START, ErrorControlTypes.SERVICE_ERROR_NORMAL, "mySvc.exe", out myTags, null, null, null); bool done = StartService(hSvc, 0, null); [/code] Code is untested and uncompiled, but should generally work as-is. Constants are declared in WinSvc.h. If you need it, PM me. | December 24, 2004, 4:00 AM |