2008. szeptember 6., szombat

Checking if a Windows feature exists - Hide your app in the Task List


Problem/Question/Abstract:

Some Windows API functions may or may not be present in your Windows version, but detecting the Windows version is not the best way to know if a function is present since it may yield a false negative if the user updated a DLL and the update includes the new function...

Answer:

To check if an API function exists, we have to load the DLL library where it is supposed to reside (calling the API LoadLibrary) and then we have to get the address of the function (calling the API GetProcAddress) which is finally used to call it. If GetProcAddress returns Nil, then the function isn't present, and if it returns a value other than Nil, then the function is present, buy we have to take into account that it isn't necessarily implemented (it may be just a placeholder, and if we call it, we will get the error code ERROR_CALL_NOT_IMPLEMENTED).

In the following example we implement a function called RegisterAsService which tries to call the API RegisterServiceProcess to register/unregister our application as a service. The function returns True if successful.

function RegisterAsService(Active: boolean): boolean;
const
  RSP_SIMPLE_SERVICE = 1;
  RSP_UNREGISTER_SERVICE = 0;
type
  TRegisterServiceProcessFunction =
    function(dwProcessID, dwType: Integer): Integer; stdcall;
var
  module: HMODULE;
  RegServProc: TRegisterServiceProcessFunction;
begin
  Result := False;
  module := LoadLibrary('KERNEL32.DLL');
  if module <> 0 then
  try
    RegServProc := GetProcAddress(module, 'RegisterServiceProcess');
    if Assigned(RegServProc) then
      if Active then
        Result := RegServProc(0, RSP_SIMPLE_SERVICE) = 1
      else
        Result := RegServProc(0, RSP_UNREGISTER_SERVICE) = 1;
  finally
    FreeLibrary(module);
  end;
end;

Notice that registering our application as a service has the side-effect of hiding our application in the Task List (in Windows Task Manager).

Sample calls:

procedure TForm1.FormCreate(Sender: TObject);
begin
  RegisterAsService(true);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  RegisterAsService(false);
end;

I guess this works only for win 9X-Me is there any way a similar move may be made under win NT/2000?

I believe for Windows NT/2000, the application must be designed to be a Windows NT/2000 service...

Perhaps you can try running your EXE with SRVANY.EXE, which runs any application as a service. Of course apps run this way won't be able to take advantage of the special operating system features available to services, but for the sake of hiding your app in the Task List, maybe it's enough, I don't know...

Copyright (c) 2001 Ernesto De Spirito
Visit: http://www.latiumsoftware.com/delphi-newsletter.php

Nincsenek megjegyzések:

Megjegyzés küldése