Show message when running program as a service

User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Show message when running program as a service

Post by Jeff Barnes »

How can you display a message to the user when a program is running as a service?
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
HunterEC
Posts: 723
Joined: Tue Sep 04, 2007 8:45 am

Re: Show message when running program as a service

Post by HunterEC »

Jeff:

How do you make a program run as a service ? Can you share the code ? Thank you very much !
User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Re: Show message when running program as a service

Post by Jeff Barnes »

Hi Hunter,

Have a look here: http://runasservice.com/
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
HunterEC
Posts: 723
Joined: Tue Sep 04, 2007 8:45 am

Re: Show message when running program as a service

Post by HunterEC »

Jeff:

Thank you very much !
User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Re: Show message when running program as a service

Post by Jeff Barnes »

You are welcome...

I use 4 batch files.
InstallService.bat - called from my installer program
StartService.bat - called form my program when exiting the user interface
StopService.bat - called from my program when opening the user interface
UninstallService.bat - used if I need to remove the service

InstallService.bat

Code: Select all

c:\YourAppFolder\RunAsService install YourServiceName "Description of Your Service" C:\YourAppFolder\YouApp.exe
net start "YourServiceName"
 

StartService.bat

Code: Select all

net start "YourServiceName"
 

StopService.bat

Code: Select all

net stop "YourServiceName"
 

UninstallService.bat

Code: Select all

net stop "YourServiceName"
c:\YourAppFolder\RunAsService uninstall "YourServiceName"
 
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Show message when running program as a service

Post by Antonio Linares »

Jeff,

Please try this:

MsgInfo( GetModuleFileName( GetInstance() ) )

and see if there is a difference running as an EXE or as a service
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Re: Show message when running program as a service

Post by Jeff Barnes »

Hi Antonio,

When I run the program normally (ie: user interface) I see the name of the exe.

When I close the program and Start the Service I do not see any messages at all.
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
Gross
Posts: 41
Joined: Sat Mar 09, 2013 8:17 am
Location: Germany Kassel
Contact:

Re: Show message when running program as a service

Post by Gross »

Services with Harbour

Testsvc.prg

Code: Select all

/*
 * $Id: testsvc.prg 18716 2012-12-03 13:52:22Z vszakats $
 */

/*
 * Harbour Project source code:
 * Windows Service API test code
 *
 * Copyright 2010 Jose Luis Capel - <jlcapel at hotmail . com>
 * www - http://harbour-project.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software; see the file COPYING.txt.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
 *
 * As a special exception, the Harbour Project gives permission for
 * additional uses of the text contained in its release of Harbour.
 *
 * The exception is that, if you link the Harbour libraries with other
 * files to produce an executable, this does not by itself cause the
 * resulting executable to be covered by the GNU General Public License.
 * Your use of that executable is in no way restricted on account of
 * linking the Harbour library code into it.
 *
 * This exception does not however invalidate any other reasons why
 * the executable file might be covered by the GNU General Public License.
 *
 * This exception applies only to the code released by the Harbour
 * Project under the name Harbour.  If you copy code from other
 * Harbour Project or Free Software Foundation releases into a copy of
 * Harbour, as the General Public License permits, the exception does
 * not apply to the code that you add in this way.  To avoid misleading
 * anyone as to the status of such modified files, you must delete
 * this exception notice from them.
 *
 * If you write modifications of your own for Harbour, it is your choice
 * whether to permit this exception to apply to your modifications.
 * If you do not wish that, delete this exception notice.
 *
 */

#if ! defined( __HBSCRIPT__HBSHELL )

#define _SERVICE_NAME "RisFilSrv"

PROCEDURE Main( cMode )

   LOCAL nError
   LOCAL cMsg

   hb_default( @cMode, "S" ) /* NOTE: Must be the default action */

   SWITCH Upper( cMode )
   CASE "I"

      IF win_serviceInstall( _SERVICE_NAME, "Harbour Windows Test Service" )
         ? "Service has been successfully installed"
      ELSE
         nError := wapi_GetLastError()
         cMsg := Space( 128 )
         wapi_FormatMessage( ,,,, @cMsg )
         ? "Error installing service: " + hb_ntos( nError ) + " " + cMsg
      ENDIF
      EXIT

   CASE "U"

      IF win_serviceDelete( _SERVICE_NAME )
         ? "Service has been deleted"
      ELSE
         nError := wapi_GetLastError()
         cMsg := Space( 128 )
         wapi_FormatMessage( ,,,, @cMsg )
         ? "Error deleting service: " + hb_ntos( nError ) + " " + cMsg
      ENDIF
      EXIT

   CASE "S"

      /* NOTE: Used when starting up as service.
               Do not invoke the executable manually with this option */

      IF win_serviceStart( _SERVICE_NAME, @SrvMain() )
         ? "Service has started OK"
      ELSE
         nError := wapi_GetLastError()
         cMsg := Space( 128 )
         wapi_FormatMessage( ,,,, @cMsg )
         ? "Service has had some problems: " + hb_ntos( nError ) + " " + cMsg
      ENDIF
      EXIT

   CASE "START"      
      IF win_serviceInitiate( _SERVICE_NAME )
         ? "Service has started OK"
      ELSE
         nError := wapi_GetLastError()
         cMsg := Space( 128 )
         wapi_FormatMessage( ,,,, @cMsg )
         ? "Service has had some problems: " + hb_ntos( nError ) + " " + cMsg
      ENDIF
      EXIT
         
   CASE "STOP"
      IF win_serviceStoped( _SERVICE_NAME )
         ? "Service has stoped OK"
      ELSE
         nError := wapi_GetLastError()
         cMsg := Space( 128 )
         wapi_FormatMessage( ,,,, @cMsg )
         ? "Service has had some problems: " + hb_ntos( nError ) + " " + cMsg
      ENDIF
      EXIT
   ENDSWITCH

   RETURN

#include "fileio.ch"

PROCEDURE SrvMain( cParam1, cParam2 )

   LOCAL n := 0
   LOCAL fhnd := hb_FCreate( hb_DirBase() + "testsvc.out", FC_NORMAL, FO_DENYNONE + FO_WRITE )
   LOCAL cParam

   hb_default( @cParam1, "" )
   hb_default( @cParam2, "" )

   FWrite( fhnd, "Startup" + hb_eol() )
   FWrite( fhnd, "|" + hb_CmdLine() + "|" + hb_eol() )
   FWrite( fhnd, "|" + cParam1 + "|" + cParam2 + "|" + hb_eol() )

   FOR EACH cParam IN hb_AParams()
      FWrite( fhnd, "Parameter " + hb_ntos( cParam:__enumIndex() ) + " >" + cParam + "<" + hb_eol() )
   NEXT

   DO WHILE win_serviceGetStatus() == WIN_SERVICE_RUNNING
      FWrite( fhnd, "Work in progress " + hb_ntos( ++n ) + hb_eol() )
      hb_idleSleep( 0.5 )
   ENDDO

   FWrite( fhnd, "Exiting..." + hb_eol() )
   FClose( fhnd )

   win_serviceSetExitCode( 0 )
   win_serviceStop()

   RETURN

#else

PROCEDURE Main()

   ? "Cannot be used in script mode."

   RETURN

#endif
 
win_svc.c

Code: Select all

/*
 * $Id: win_svc.c 18716 2012-12-03 13:52:22Z vszakats $
 */

/*
 * Harbour Project source code:
 * Windows Service API
 *
 * Copyright 2010 Jose Luis Capel - <jlcapel at hotmail . com>
 * www - http://harbour-project.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software; see the file COPYING.txt.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
 *
 * As a special exception, the Harbour Project gives permission for
 * additional uses of the text contained in its release of Harbour.
 *
 * The exception is that, if you link the Harbour libraries with other
 * files to produce an executable, this does not by itself cause the
 * resulting executable to be covered by the GNU General Public License.
 * Your use of that executable is in no way restricted on account of
 * linking the Harbour library code into it.
 *
 * This exception does not however invalidate any other reasons why
 * the executable file might be covered by the GNU General Public License.
 *
 * This exception applies only to the code released by the Harbour
 * Project under the name Harbour.  If you copy code from other
 * Harbour Project or Free Software Foundation releases into a copy of
 * Harbour, as the General Public License permits, the exception does
 * not apply to the code that you add in this way.  To avoid misleading
 * anyone as to the status of such modified files, you must delete
 * this exception notice from them.
 *
 * If you write modifications of your own for Harbour, it is your choice
 * whether to permit this exception to apply to your modifications.
 * If you do not wish that, delete this exception notice.
 *
 */

#include "hbwapi.h"
#include "hbapiitm.h"
#include "hbvm.h"
#include "hbstack.h"

#if ! defined( HB_OS_WIN_CE )

#if defined( __POCC__ ) || defined( __XCC__ )
#  include <winsvc.h>   /* it's disabled by WIN32_LEAN_AND_MEAN */
#endif

static SERVICE_STATUS        s_ServiceStatus;
static SERVICE_STATUS_HANDLE s_hStatus;
static PHB_ITEM              s_pHarbourEntryFunc = NULL;
static TCHAR                 s_lpServiceName[ 256 ];

/* Control handler function */
static VOID WINAPI hbwin_SvcControlHandler( DWORD fdwControl )
{
   switch( fdwControl )
   {
      case SERVICE_CONTROL_STOP:
         s_ServiceStatus.dwWin32ExitCode = 0;
         s_ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
         return;

      case SERVICE_CONTROL_SHUTDOWN:
         s_ServiceStatus.dwWin32ExitCode = 0;
         s_ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
         return;
   }

   SetServiceStatus( s_hStatus, &s_ServiceStatus ); /* Report current status */
}

static VOID WINAPI hbwin_SvcMainFunction( DWORD dwArgc, LPTSTR * lpszArgv )
{
   s_ServiceStatus.dwServiceType             = SERVICE_WIN32;
   s_ServiceStatus.dwCurrentState            = SERVICE_START_PENDING;
   s_ServiceStatus.dwControlsAccepted        = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
   s_ServiceStatus.dwWin32ExitCode           = 0;
   s_ServiceStatus.dwServiceSpecificExitCode = 0;
   s_ServiceStatus.dwCheckPoint              = 0;
   s_ServiceStatus.dwWaitHint                = 0;

   s_hStatus = RegisterServiceCtrlHandler( s_lpServiceName, ( LPHANDLER_FUNCTION ) hbwin_SvcControlHandler );

   if( s_hStatus != ( SERVICE_STATUS_HANDLE ) 0 )
   {
      if( s_pHarbourEntryFunc != NULL )
      {
         if( hb_vmRequestReenterExt() )
         {
            DWORD i;
            int iArgCount = 0;

            /* We report the running status to SCM. */
            s_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
            SetServiceStatus( s_hStatus, &s_ServiceStatus );

            hb_vmPushEvalSym();
            hb_vmPush( s_pHarbourEntryFunc );

            for( i = 1; i < dwArgc; ++i )
            {
               PHB_ITEM pItem = hb_stackAllocItem();

               HB_ITEMPUTSTR( pItem, lpszArgv[ i ] );
               if( hb_cmdargIsInternal( hb_itemGetCPtr( pItem ), NULL ) )
                  hb_stackPop();
               else
                  ++iArgCount;
            }

            hb_vmSend( ( HB_USHORT ) iArgCount );

            hb_vmRequestRestore();
         }
         else
            HB_TRACE( HB_TR_DEBUG, ( "HVM stack not available" ) );
      }
      else
         HB_TRACE( HB_TR_DEBUG, ( "Harbour service entry function not found" ) );
   }
   else
      HB_TRACE( HB_TR_DEBUG, ( "Error registering service" ) );
}

#endif

HB_FUNC( WIN_SERVICEGETSTATUS )
{
#if ! defined( HB_OS_WIN_CE )
   hb_retnl( s_ServiceStatus.dwCurrentState );
#else
   hb_retnl( 0 );
#endif
}

HB_FUNC( WIN_SERVICESETSTATUS )
{
#if ! defined( HB_OS_WIN_CE )
   s_ServiceStatus.dwCurrentState = ( DWORD ) hb_parnl( 1 );
   hb_retl( SetServiceStatus( s_hStatus, &s_ServiceStatus ) );
#else
   hb_retl( HB_FALSE );
#endif
}

HB_FUNC( WIN_SERVICESETEXITCODE )
{
#if ! defined( HB_OS_WIN_CE )
   s_ServiceStatus.dwWin32ExitCode = ( DWORD ) hb_parnl( 1 );
   hb_retl( SetServiceStatus( s_hStatus, &s_ServiceStatus ) );
#else
   hb_retl( HB_FALSE );
#endif
}

HB_FUNC( WIN_SERVICESTOP )
{
#if ! defined( HB_OS_WIN_CE )
   s_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
   SetServiceStatus( s_hStatus, &s_ServiceStatus );
#endif
}

HB_FUNC( WIN_SERVICEINSTALL )
{
   HB_BOOL bRetVal = HB_FALSE;

#if ! defined( HB_OS_WIN_CE )

   void * hPath;
   LPCTSTR lpPath = HB_PARSTR( 3, &hPath, NULL );

   TCHAR lpPathBuffer[ MAX_PATH ];

   if( lpPath == NULL )
   {
      if( GetModuleFileName( NULL, lpPathBuffer, HB_SIZEOFARRAY( lpPathBuffer ) ) )
         lpPath = lpPathBuffer;
      else
         hbwapi_SetLastError( GetLastError() );
   }

   if( lpPath )
   {
      SC_HANDLE schSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

      if( schSCM )
      {
         SC_HANDLE schSrv;

         void * hServiceName;
         void * hDisplayName;

         LPCTSTR lpServiceName = HB_PARSTRDEF( 1, &hServiceName, NULL );
         LPCTSTR lpDisplayName = HB_PARSTRDEF( 2, &hDisplayName, NULL );

         schSrv = CreateService( schSCM,                    /* SCM database */
                                 lpServiceName,             /* name of service */
                                 lpDisplayName,             /* service name to display */
                                 SERVICE_ALL_ACCESS,        /* desired access */
                                 SERVICE_WIN32_OWN_PROCESS, /* service type */
                                 HB_ISNUM( 4 ) ? ( DWORD ) hb_parnl( 4 ) : SERVICE_DEMAND_START,
                                                            /* start type */
                                 SERVICE_ERROR_NORMAL,      /* error control type */
                                 lpPath,                    /* path to service's binary */
                                 NULL,                      /* no load ordering group */
                                 NULL,                      /* no tag identifier */
                                 NULL,                      /* no dependencies */
                                 NULL,                      /* LocalSystem account */
                                 NULL );                    /* no password */

         if( schSrv )
         {
            bRetVal = HB_TRUE;

            CloseServiceHandle( schSrv );
         }
         else
            hbwapi_SetLastError( GetLastError() );

         hb_strfree( hServiceName );
         hb_strfree( hDisplayName );

         CloseServiceHandle( schSCM );
      }
      else
         hbwapi_SetLastError( GetLastError() );
   }

   hb_strfree( hPath );

#endif
   hb_retl( bRetVal );
}

HB_FUNC( WIN_SERVICEDELETE )
{
   HB_BOOL bRetVal = HB_FALSE;

#if ! defined( HB_OS_WIN_CE )
   SC_HANDLE schSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

   if( schSCM )
   {
      void * hServiceName;

      SC_HANDLE schSrv = OpenService( schSCM,
                                      HB_PARSTRDEF( 1, &hServiceName, NULL ),
                                      SERVICE_ALL_ACCESS );

      if( schSrv )
      {
         /* TODO: check if service is up and then stop it */

         bRetVal = ( HB_BOOL ) DeleteService( schSrv );

         CloseServiceHandle( schSrv );
      }
      else
         hbwapi_SetLastError( GetLastError() );

      hb_strfree( hServiceName );

      CloseServiceHandle( schSCM );
   }
   else
      hbwapi_SetLastError( GetLastError() );
#endif
   hb_retl( bRetVal );
}

HB_FUNC( WIN_SERVICESTART )
{
   HB_BOOL bRetVal = HB_FALSE;

#if ! defined( HB_OS_WIN_CE )
   PHB_ITEM pEntryFunc;

   SERVICE_TABLE_ENTRY lpServiceTable[ 2 ];

   HB_ITEMCOPYSTR( hb_param( 1, HB_IT_STRING ), s_lpServiceName, HB_SIZEOFARRAY( s_lpServiceName ) );

   if( s_pHarbourEntryFunc )
   {
      hb_itemRelease( s_pHarbourEntryFunc );
      s_pHarbourEntryFunc = NULL;
   }

   pEntryFunc = hb_param( 2, HB_IT_BLOCK | HB_IT_SYMBOL );

   if( pEntryFunc )
      s_pHarbourEntryFunc = hb_itemNew( pEntryFunc );

   lpServiceTable[ 0 ].lpServiceName = s_lpServiceName;
   lpServiceTable[ 0 ].lpServiceProc = ( LPSERVICE_MAIN_FUNCTION ) hbwin_SvcMainFunction;

   lpServiceTable[ 1 ].lpServiceName = NULL;
   lpServiceTable[ 1 ].lpServiceProc = NULL;

   if( StartServiceCtrlDispatcher( lpServiceTable ) )
      bRetVal = HB_TRUE;
   else
      hbwapi_SetLastError( GetLastError() );

#endif
   hb_retl( bRetVal );
}
HB_FUNC( WIN_SERVICEINITIATE )
{
   HB_BOOL bRetVal = HB_FALSE;
#if ! defined( HB_OS_WIN_CE )
// open a handle to the SCM
SC_HANDLE schSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

if( schSCM )
{
      // open a handle to the service
      void * hServiceName;

      SC_HANDLE schSrv = OpenService( schSCM, HB_PARSTRDEF( 1, &hServiceName, NULL ), GENERIC_EXECUTE );
      if( schSrv )
      {
         if( ! ( bRetVal = StartService( schSrv, 0, NULL ) ) )
            hbwapi_SetLastError( GetLastError() );

      }else
         hbwapi_SetLastError( GetLastError() );

      hb_strfree( hServiceName );

      CloseServiceHandle( schSrv );
      CloseServiceHandle( schSCM );

   }else
      hbwapi_SetLastError( GetLastError() );

#endif
   hb_retl( bRetVal );
}


HB_FUNC( WIN_SERVICESTOPED )
{
   HB_BOOL bRetVal = HB_FALSE;
#if ! defined( HB_OS_WIN_CE )
// open a handle to the SCM
SC_HANDLE schSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if( schSCM )
{
  void * hServiceName;
  // open a handle to the service
  SC_HANDLE schSrv = OpenService( schSCM, HB_PARSTRDEF( 1, &hServiceName, NULL ), GENERIC_EXECUTE );
  if( schSrv ){
     // send the STOP control request to the service
     SERVICE_STATUS status;
     ControlService( schSrv, SERVICE_CONTROL_STOP, &status );
     CloseServiceHandle( schSrv );
     CloseServiceHandle( schSCM );

         if( ( bRetVal = status.dwCurrentState != SERVICE_STOPPED ) )
            hbwapi_SetLastError( GetLastError() );

         hb_strfree( hServiceName );

  }else
         hbwapi_SetLastError( GetLastError() );

   }else
      hbwapi_SetLastError( GetLastError() );
#endif
   hb_retl( bRetVal );
}

 
Manfred Groß
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Show message when running program as a service

Post by Antonio Linares »

Jeff,

Ok, thats because services are not allowed to show a MsgInfo()

Change it into a call to LogFile() or OutputDebugString()
regards, saludos

Antonio Linares
www.fivetechsoft.com
Gale FORd
Posts: 663
Joined: Mon Dec 05, 2005 11:22 pm
Location: Houston
Contact:

Re: Show message when running program as a service

Post by Gale FORd »

You can allow service to interact with the desktop.
See if the info below helps.
Although typically services do not have a user interface, developers can add forms and other UI components. In this case, the "Allow service to interact with desktop" should be checked on the Logon tab in the Service properties dialog (though care should be taken with this approach as this can cause a security risk since any logged in user would be able to interact with the service)
User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Re: Show message when running program as a service

Post by Jeff Barnes »

Tried OutputDebugString("TEST") ... nothing is displayed.
Verified that I have "allow service to interact with desktop" checked ... nothing is displayed.

I have come up with a work-around ... Since the service interacts with another running program I can use the Running Program to display the messages I need.

Thanks for all the input with this one :)
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Show message when running program as a service

Post by Antonio Linares »

Jeff,
Tried OutputDebugString("TEST") ... nothing is displayed
Did you had dbwin32.exe running to see the output messages from OutputDebugString() ?

https://bitbucket.org/fivetech/fivewin- ... bwin32.zip
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Re: Show message when running program as a service

Post by Jeff Barnes »

Just tried with DBWIN32 running ... still nothing is displayed.
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
Gale FORd
Posts: 663
Joined: Mon Dec 05, 2005 11:22 pm
Location: Houston
Contact:

Re: Show message when running program as a service

Post by Gale FORd »

There is another way using Windows Interactive Service.

https://msdn.microsoft.com/en-us/librar ... 85%29.aspx
User avatar
rhlawek
Posts: 165
Joined: Sun Jul 22, 2012 7:01 pm

Re: Show message when running program as a service

Post by rhlawek »

Regarding output from OutputDebugString(): Unless you've explicitly configured the service to run under a specific account, the service will be running as System. The debug viewer running under your desktop account likely doesn't have sufficient privilege to see these messages. That is certainly my experience. I happen to use DebugView from sysinternals. For it to see OutputDebugString() messages Capture Global Win32 messages must be enabled, which in DebugView is disabled by default. To enable that requires that I launch DebugView as Administrator.

It shouldn't matter for the above paragraph but I also don't use any external helper for any of my services (let's me stay with only a single .exe for an app). I've used the service manager control example from the harbour hbwin contribution, it's pretty straightforward.

Robb
Post Reply