Tricky is right. But doable. I added the following to my library...
----------
private const System.Int32 SERVICE_CONFIG_DESCRIPTION = 1 ;
private const System.Int32 SERVICE_CHANGE_CONFIG = 0x0002 ;
private const System.Int32 STANDARD_RIGHTS_REQUIRED =
0x000F0000 ;
private const System.Int32 SC_MANAGER_CONNECT = 0x0001 ;
private const System.Int32 SC_MANAGER_CREATE_SERVICE = 0x0002 ;
private const System.Int32 SC_MANAGER_ENUMERATE_SERVICE = 0x0004 ;
private const System.Int32 SC_MANAGER_LOCK = 0x0008 ;
private const System.Int32 SC_MANAGER_QUERY_LOCK_STATUS = 0x0010 ;
private const System.Int32 SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020 ;
private const System.Int32 SC_MANAGER_ALL_ACCESS =
(
STANDARD_RIGHTS_REQUIRED |
SC_MANAGER_CONNECT |
SC_MANAGER_CREATE_SERVICE |
SC_MANAGER_ENUMERATE_SERVICE |
SC_MANAGER_LOCK |
SC_MANAGER_QUERY_LOCK_STATUS |
SC_MANAGER_MODIFY_BOOT_CONFIG
) ;
internal struct SERVICE_DESCRIPTION
{
internal System.IntPtr lpDescription ;
}
[System.Runtime.InteropServices.DllImport ( "Advapi32" ,
SetLastError=true , EntryPoint="OpenSCManager" )]
private unsafe static extern System.IntPtr
API_OpenSCManager
(
string lpMachineName
,
string lpDataBaseName
,
int dwDesiredAccess
) ;
[System.Runtime.InteropServices.DllImport ( "Advapi32" ,
SetLastError=true , EntryPoint="OpenService" )]
private unsafe static extern System.IntPtr
API_OpenService
(
System.IntPtr hSCManager
,
string lpServiceName
,
int dwDesiredAccess
) ;
[System.Runtime.InteropServices.DllImport ( "Advapi32" ,
SetLastError=true , EntryPoint="CloseServiceHandle" )]
private unsafe static extern bool
API_CloseServiceHandle
(
System.IntPtr hSCObject
) ;
[System.Runtime.InteropServices.DllImport ( "Advapi32" ,
SetLastError=true , EntryPoint="ChangeServiceConfig2" )]
private unsafe static extern bool
API_ChangeServiceConfig2
(
System.IntPtr hService
,
int dwInfoLevel
,
System.IntPtr lpInfo
) ;
public unsafe static bool
SetServiceDescription
(
string ServiceName
,
string Description
)
{
bool result = false ;
int InfoLevel = SERVICE_CONFIG_DESCRIPTION ;
byte* temp = stackalloc byte [ Description.Length+1 ] ;
for ( int runner = 0 ; runner < Description.Length ; runner++ )
{
temp [ runner] = (byte) Description [ runner ] ;
}
temp [ Description.Length ] = 0 ;
SERVICE_DESCRIPTION Info ;
Info.lpDescription = new System.IntPtr ( temp ) ;
System.IntPtr schSCManager = API_OpenSCManager
(
null
,
null
,
SC_MANAGER_ALL_ACCESS
) ;
System.IntPtr hService = API_OpenService
(
schSCManager
,
ServiceName
,
SERVICE_CHANGE_CONFIG
) ;
result = API_ChangeServiceConfig2
(
hService
,
InfoLevel
,
new System.IntPtr ( &Info )
) ;
API_CloseServiceHandle
(
hService
) ;
return ( result ) ;
}
----------
Then in my ServiceThread class I added...
public void
AfterInstallEventHandler
(
object sender
,
System.Configuration.Install.InstallEventArgs e
)
{
PIEBALD.Lib.LibAPI.SetServiceDescription ( this.ServiceName ,
this.description ) ;
}
----------
And in my ServiceInstaller class I added...
serviceInstaller.AfterInstall += new
System.Configuration.Install.InstallEventHandler
( srv.AfterInstallEventHandler ) ;