Service registry update

G

Guest

Guest
Archived from groups: microsoft.public.windowsnt.registry (More info?)

Hello,

In an installer,
I update a service registry key to
"Allow service to interact with desktop"
HKLM\System\CurrentControlSet\Services\<MyService>\Type DWORD 272
(272 instead of the default 16)

This has no effect until I do one of two things.
- reboot the machine, or
- 1) right-click properties on the service
(in the services mmc),
2) unselect and reselect
"Allow service to interact with desktop"
(this highlights the apply button)
3) click APPLY
4) right-click restart the service

I found this Google article
that mentions the same feature, without
the solution
http://groups.google.com/groups?q=%22Allow+service+to+interact+with+desktop%22&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=b5f34828.0204261503.5142881e%40posting.google.com&rnum=3

I investigated a little further, and here is my understanding
of the problem :
- services.exe is in charge of starting/stopping services.
- it reads once the environment variables and relevant registry
keys when the machine is booted up, and gives these to
the services it stops and starts
- it can't be stopped and restarted without rebooting
- it is not informed of the registry key change I perform
during installation
- until I click apply on the mmc service property window
or I reboot the machine

Does anybody know which API call is equivalent to clicking
Apply in the service properties window. I want to
avoid rebooting the machine just to change a single
bit in the registry when I know that it is possible
to avoid it.

Any information appreciated. Thanks in advance.

-- Benoit

platforms : w2k sp2, wxp sp1
 
G

Guest

Guest
Archived from groups: microsoft.public.windowsnt.registry (More info?)

From a command prompt
net start "service name"

--
Regards,

Dave Patrick ....Please no email replies - reply in newsgroup.
Microsoft Certified Professional
Microsoft MVP [Windows]
http://www.microsoft.com/protect


"Benoit Gennart" wrote:
| Hello,
|
| In an installer,
| I update a service registry key to
| "Allow service to interact with desktop"
| HKLM\System\CurrentControlSet\Services\<MyService>\Type DWORD 272
| (272 instead of the default 16)
|
| This has no effect until I do one of two things.
| - reboot the machine, or
| - 1) right-click properties on the service
| (in the services mmc),
| 2) unselect and reselect
| "Allow service to interact with desktop"
| (this highlights the apply button)
| 3) click APPLY
| 4) right-click restart the service
|
| I found this Google article
| that mentions the same feature, without
| the solution
|
http://groups.google.com/groups?q=%22Allow+service+to+interact+with+desktop%22&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=b5f34828.0204261503.5142881e%40posting.google.com&rnum=3
|
| I investigated a little further, and here is my understanding
| of the problem :
| - services.exe is in charge of starting/stopping services.
| - it reads once the environment variables and relevant registry
| keys when the machine is booted up, and gives these to
| the services it stops and starts
| - it can't be stopped and restarted without rebooting
| - it is not informed of the registry key change I perform
| during installation
| - until I click apply on the mmc service property window
| or I reboot the machine
|
| Does anybody know which API call is equivalent to clicking
| Apply in the service properties window. I want to
| avoid rebooting the machine just to change a single
| bit in the registry when I know that it is possible
| to avoid it.
|
| Any information appreciated. Thanks in advance.
|
| -- Benoit
|
| platforms : w2k sp2, wxp sp1
 
G

Guest

Guest
Archived from groups: microsoft.public.windowsnt.registry (More info?)

Dave,

Thanks for your reply.
That turned out to be not enough
(but a useful step)
I just found the solution : a call
to ChangeServiceConfig (see program
below), follow by a net stop / net
start.

Also, the serice is apache, which I can
restart in two ways :
apache -n "Apache" -k restart
net stop Apache & net start Apache
Only the second combined with ChangeServiceConfig
does the trick for me.

-- Benoit

"Dave Patrick" <mail@NoSpam.DSPatrick.com> wrote in message news:<#JyW3r5IEHA.2144@TK2MSFTNGP12.phx.gbl>...
> From a command prompt
> net start "service name"
>
> --
> Regards,
>
> Dave Patrick ....Please no email replies - reply in newsgroup.
> Microsoft Certified Professional
> Microsoft MVP [Windows]
> http://www.microsoft.com/protect
>

// Use at your own risk
// SAID stands for Service, Allow Interaction with Desktop
// based on http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/starting_a_service.asp

#include <windows.h>
#include <stdio.h>

// BOOL ChangeServiceConfig(
// SC_HANDLE hService // handle to service
// DWORD dwServiceType, // type of service
// DWORD dwStartType, // when to start service
// DWORD dwErrorControl, // severity if service fails to start
// LPCTSTR lpBinaryPathName, // pointer to service binary file name
// LPCTSTR lpLoadOrderGroup, // pointer to load ordering group name
// LPDWORD lpdwTagId, // pointer to variable to get tag
identifier
// LPCTSTR lpDependencies, // pointer to array of dependency
names
// LPCTSTR lpServiceStartName,
// // pointer to account name of service
// LPCTSTR lpPassword, // pointer to password for service account
// LPCTSTR lpDisplayName // pointer to display name
// );

#ifdef _WIN32
char* traceFileNameS = "C:\\temp\\said-trace.txt" ;
#else
char* traceFileNameS = "/tmp/said-trace.txt" ;
#endif

extern "C" void saidTrace (char* string, ...)

{
char str[4096] ;
char *strP = str ;
va_list args ;

va_start (args, string) ;
vsprintf (strP, string, args) ;

FILE* traceFileP = fopen (traceFileNameS, "a+") ;
if (traceFileP != 0) {
fprintf (traceFileP, "%s\n", str) ;
fflush (traceFileP) ;
fclose (traceFileP) ;
}
va_end (args) ;

}



int ServiceAllowInteractionWithDesktop (SC_HANDLE schSCManager, char*
serviceName)
{
SC_HANDLE schService;
SERVICE_STATUS ssStatus;
DWORD dwOldCheckPoint;
DWORD dwStartTickCount;
DWORD dwWaitTime;

saidTrace ("%s:%i: opening service %s", __FILE__, __LINE__,
serviceName) ;

schService = OpenService(
schSCManager, // SCM database
serviceName, // service name
SERVICE_ALL_ACCESS);

if (schService == NULL)
{
saidTrace ("%s:%i: problem opening service '%s'", __FILE__, __LINE__,
serviceName) ;
return -1 ;
}

saidTrace ("%s:%i: SAID %i %i %i", __FILE__, __LINE__
, SERVICE_WIN32_OWN_PROCESS , SERVICE_INTERACTIVE_PROCESS
, SERVICE_WIN32_OWN_PROCESS |
SERVICE_INTERACTIVE_PROCESS
) ;

saidTrace ("%s:%i: changing service %s interactivity", __FILE__,
__LINE__, serviceName) ;
int ret = ChangeServiceConfig (schService, 272
, /* dwStartType */ SERVICE_NO_CHANGE
, /* dwErrorControl */ SERVICE_NO_CHANGE
, /* lpBinaryPathName */ 0
, /* ldLoadOrderGroup */ 0
, /* lddwTagID */ 0
, /* lpDependencies */ 0
, /* lpServiceStartName */ 0
, /* lpPassword */ 0
, /* ldDisplayName */ 0
) ;

if (ret == 0) {
LPVOID lpMsgBuf;
if (!FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL ))
{
// Handle the error.
saidTrace ("%s:%i: Failed to change registry setting (%i)",
GetLastError());
return -2 ;
}

saidTrace ("%s:%i: Failed to change registry setting (%i, %s)",
__FILE__, __LINE__, GetLastError(), lpMsgBuf);
LocalFree( lpMsgBuf );

return -3 ;
}

saidTrace ("%s:%i: closing service %s", __FILE__, __LINE__,
serviceName) ;
CloseServiceHandle (schService) ;
return 0 ;

#ifdef IGNORE_THIS
if (!StartService(
schService, // handle to service
0, // number of arguments
NULL) ) // no arguments
{
return 0;
}
else
{
saidTrace("Service start pending.");
}

// Check the status until the service is no longer start pending.

if (!QueryServiceStatus(
schService, // handle to service
&ssStatus) ) // address of status information structure
{
return 0;
}

// Save the tick count and initial checkpoint.

dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;

while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
{
// Do not wait longer than the wait hint. A good interval is
// one tenth the wait hint, but no less than 1 second and no
// more than 10 seconds.

dwWaitTime = ssStatus.dwWaitHint / 10;

if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 10000 )
dwWaitTime = 10000;

Sleep( dwWaitTime );

// Check the status again.

if (!QueryServiceStatus(
schService, // handle to service
&ssStatus) ) // address of structure
break;

if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
{
// The service is making progress.

dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
{
// No progress made within the wait hint
break;
}
}
}

CloseServiceHandle(schService);

if (ssStatus.dwCurrentState == SERVICE_RUNNING)
{
saidTrace("StartService SUCCESS.");
return 1;
}
else
{
saidTrace("\nService not started. ");
saidTrace(" Current State: %d", ssStatus.dwCurrentState);
saidTrace(" Exit Code: %d", ssStatus.dwWin32ExitCode);
saidTrace(" Service Specific Exit Code: %d",
ssStatus.dwServiceSpecificExitCode);
saidTrace(" Check Point: %d", ssStatus.dwCheckPoint);
saidTrace(" Wait Hint: %d", ssStatus.dwWaitHint);
return 0;
}
#endif
}


int main (int argc, char* argv[])

{
if (argc != 2) {
saidTrace ("%s:%i: Usage %s <quoted service name>", __FILE__,
__LINE__, argv[1]) ;
return -1 ;
}

saidTrace ("%s:%i: Opening service-controller manager", __FILE__,
__LINE__) ;
SC_HANDLE schSCManager ;
schSCManager = OpenSCManager ("", SERVICES_ACTIVE_DATABASE,
SC_MANAGER_ALL_ACCESS) ;
if (schSCManager == 0) {
saidTrace ("%s:%i: Problem opening service-controller manager",
__FILE__, __LINE__) ;
return -2 ;
}
int ret = ServiceAllowInteractionWithDesktop (schSCManager,
argv[1]) ;
if (ret != 0) {
return (-3 + ret) ;
}

saidTrace ("%s:%i: Closing service-controller manager", __FILE__,
__LINE__) ;
CloseServiceHandle (schSCManager) ;
return 0 ;
}
 

martinyarwood

Distinguished
May 14, 2010
1
0
18,510
It depresses me that "Microsoft Certified Professionals " show such a poor understanding of there own area of expertise, the reply above completely misses the point, how is net start going to help when the configuration has not been 'recognised' as having been changed. When you write the registry entry on its own it doesn't work until reboot but you can get it to work with the sc command. As always Microsofts documentation is poor and you might be led to believe

sc config service-name type= interact

[SC] ChangeServiceConfig FAILED 87:

The parameter is incorrect.

would work as the documentation says

type= <own|share|interact|kernel|filesys|rec|adapt>

but you'd be wrong, you need

sc config sentinel-switch type= own type= interact

now surely thats better than writing your own code to do it
--
Martin Yarwood Chief Engineer SENTINEL, C++ development. XCH 8555
Selex Communications Grange Road, Christchurch , Dorset BH23 4JE, UK