Search code examples
servicedelphi-xe

RegisterHotKey from Windows Service application


If I call RegisterHotKey() from the ServiceStart procedure it will fail with below error:

ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION

I couldn't find much information on this so I created a thread, made a window (CreateWindow) and called RegisterHotKey() from this context; However, it returns the same error, What is the Proper way to register a hotkey from a Service application?

Here is my code:

Function Makewnd(): integer;
Var
  Hwnd: THandle;
  uMsg: TMsg;
Begin
  Hwnd := CreateWindow('STATIC', 'DummyWindow', 0, 0, 0, 100, 100, HWND_MESSAGE, 0, HInstance, Nil);

  Writelog(pchar('CreateWindow HWND->'+inttohex(hwnd,8)));

  If (RegisterHotKey(Hwnd, 7000, MOD_CONTROL or MOD_ALT, VK_F12) = TRUE) Then
    writelog('hotkey set: MOD_CONTROL or MOD_ALT, VK_F12')
  Else begin
    Writelog(PWideChar('Error: '+inttostr(getlasterror())));
  End;

  while (GetMessage(uMsg, Hwnd, 0, 0) = TRUE) do
    case uMsg.message of
      WM_HOTKEY:
      Begin
        Writelog(PWideChar('Hotkey! ID-> ' + inttostr(uMsg.wParam)));
      End;

    end;
    Writelog('GetMessage=false');
    Result := 0;
End;

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  Service4.Controller(CtrlCode);
end;

function TService4.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

procedure TService4.ServiceExecute(Sender: TService);
begin
  Writelog('ServiceExecuteing');
  while not Terminated do
  Begin
    ServiceThread.ProcessRequests(TRUE);
  End;
end;

procedure TService4.ServiceStart(Sender: TService; var Started: Boolean);
Var
  TID: DWORD;
  Handle: THandle;
begin
  writelog('ServiceStart');
  Handle := CreateThread(Nil, 0, @makewnd, Nil, 0, TID);
  //not using handle right now
end;

Solution

  • You can't

    To add to what Ken said, Interactive Services were eliminated when Session 0 Isolation was introduced in Vista. Prior to that, a service could interact with the user desktop (but only the desktop of the first user to login) if the SERVICE_INTERACTIVE_PROCESS flag was specified in the call to CreateService(). That flag is no longer supported, and services can no longer interact with any user desktops. – Remy Lebeau