Running wxWidgets app as a windows service

If you have a cool piece of software to share, but you are not hosting it officially yet, please dump it in here. If you have code snippets that are useful, please donate!
viraptor
Knows some wx things
Knows some wx things
Posts: 31
Joined: Sat Jan 08, 2005 3:37 pm

Running wxWidgets app as a windows service

Post by viraptor »

Windows service with wx.
Couldn't find any example on the net, so here it goes - it installs / uninstalls itself when passed correct arguments. --svc, to run code.

main.h:

Code: Select all

SERVICE_STATUS svcStatus;
SERVICE_STATUS_HANDLE svcStatusHnd;
void WINAPI svcStart(DWORD argc, LPTSTR *argv);
SERVICE_TABLE_ENTRY   dispatchTable[] =
{
    { "SampleService", &svcStart      },
    { NULL,              NULL          }
};

SC_HANDLE m_globalSCM;

void WINAPI svcHandler(DWORD opcode);

class MainApp: public wxApp
{
    private:
        bool openSCM(void);
        void closeSCM(void);
        bool isInstalled(void);
        void install(void);
        void uninstall(void);
    public:
        virtual bool OnInit();
};
base.cpp:

Code: Select all

IMPLEMENT_APP_NO_MAIN(MainApp)

HINSTANCE g_hInstance;
HINSTANCE g_hPrevInstance;
wxCmdLineArgType g_lpCmdLine;
int g_nCmdShow;

extern "C" int WINAPI WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    wxCmdLineArgType lpCmdLine,
    int nCmdShow)
{
    if(strstr(lpCmdLine, "--svc")==NULL) {
        return wxEntry(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
    } else {
        g_hInstance = hInstance;
        g_hPrevInstance = hPrevInstance;
        g_lpCmdLine = lpCmdLine;
        g_nCmdShow = nCmdShow;
        StartServiceCtrlDispatcher(dispatchTable);
    }
}

bool MainApp::OnInit()
{
    wxString usage = "--install\n--uninstall";
    if(argc!=2) {
        wxMessageDialog(NULL, usage, "SampleService", wxOK).ShowModal();
        return FALSE;
    }
    
    wxString command = argv[1];
    if(command=="--svc") {
        // INIT THE REAL SERVICE HERE AND LET THE MAIN LOOP RUN
        return TRUE;
    } else if(command=="--install") {
        if(isInstalled()) {
            wxMessageDialog(NULL, "SampleService already installed", "SampleService", wxOK).ShowModal();
        } else {
            install();
        }
    } else if(command=="--uninstall") {
        if(!isInstalled()) {
            wxMessageDialog(NULL, "SampleService was not installed.", "SampleService", wxOK).ShowModal();
        } else {
            uninstall();
        }
    } else {
       wxMessageDialog(NULL, usage, "SampleService", wxOK).ShowModal();
    }
    return FALSE;
}

bool MainApp::isInstalled(void) {
    bool found;
    openSCM();
    SC_HANDLE svc = OpenService(
        m_globalSCM,
        TEXT("SampleService"),
        SERVICE_ALL_ACCESS);
    if(svc) {
        found=true;
        CloseServiceHandle(svc);
    } else found=false;
    closeSCM();
    return found;
}

bool MainApp::openSCM(void) {
    m_globalSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

    if (NULL == m_globalSCM) {
        wxMessageDialog(NULL, wxString::Format("openSCM error %d", GetLastError()), "SampleService", wxOK).ShowModal();
        return FALSE;
    } else
        return TRUE;
}

void MainApp::closeSCM(void) {
    CloseServiceHandle(m_globalSCM);
}

void MainApp::install(void) {
    openSCM();
    SC_HANDLE schService = CreateService(
        m_globalSCM,
        TEXT("SampleService"),        // name of service
        "SampleService",
        SERVICE_ALL_ACCESS,
        SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // remove interactive if not using gui
        SERVICE_DEMAND_START,
        SERVICE_ERROR_NORMAL,
        wxString::Format("\"%s\" --svc", argv[0]),
        NULL,
        NULL,
        NULL,
        NULL,
        NULL);
    if(schService==NULL)
        wxMessageDialog(NULL, wxString::Format("createSvc error %d", GetLastError()), "SampleService", wxOK).ShowModal();
    else
        wxMessageDialog(NULL, "SampleService installed.", "SampleService", wxOK).ShowModal();
    closeSCM();
}

void MainApp::uninstall(void) {
    openSCM();
    SC_HANDLE svc = OpenService(
        m_globalSCM,
        TEXT("SampleService"),
        SERVICE_ALL_ACCESS);
    SERVICE_STATUS status;
    ControlService(svc, SERVICE_CONTROL_STOP, &status);
    if(!DeleteService(svc))
        wxMessageDialog(NULL, wxString::Format("deleteSvc error %d", GetLastError()), "SampleService", wxOK).ShowModal();
    else
        wxMessageDialog(NULL, "SampleService uninstalled.", "SampleService", wxOK).ShowModal();
    CloseServiceHandle(svc);
    closeSCM();
}

void WINAPI svcStart(DWORD argc, LPTSTR *argv) {
    svcStatusHnd = RegisterServiceCtrlHandler("SampleService", &svcHandler);
    if(!svcStatusHnd) {
        MessageBox(NULL, "svcHandler error", "SampleService", MB_OK);
    }
    svcStatus.dwServiceType        = SERVICE_WIN32;
    svcStatus.dwCurrentState       = SERVICE_START_PENDING;
    svcStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP;
    svcStatus.dwWin32ExitCode      = 0;
    svcStatus.dwServiceSpecificExitCode = 0;
    svcStatus.dwCurrentState       = SERVICE_RUNNING;
    svcStatus.dwCheckPoint         = 0;
    svcStatus.dwWaitHint           = 0;
    if(SetServiceStatus(svcStatusHnd, &svcStatus))
        wxEntry(g_hInstance, g_hPrevInstance, g_lpCmdLine, g_nCmdShow);
    return;
}

void WINAPI svcHandler (DWORD opcode) {
   DWORD status;

   switch(opcode)
   {
      case SERVICE_CONTROL_PAUSE:
         svcStatus.dwCurrentState = SERVICE_PAUSED;
         break;

      case SERVICE_CONTROL_CONTINUE:
         svcStatus.dwCurrentState = SERVICE_RUNNING;
         break;

      case SERVICE_CONTROL_STOP:
         svcStatus.dwWin32ExitCode = 0;
         svcStatus.dwCurrentState  = SERVICE_STOPPED;
         svcStatus.dwCheckPoint    = 0;
         svcStatus.dwWaitHint      = 0;

         if (!SetServiceStatus (svcStatusHnd, &svcStatus))
         {
            status = GetLastError();
            MessageBox(NULL, "svcStatusStop error", "SampleService", MB_OK);
         }

// exit prog
         return;

      case SERVICE_CONTROL_INTERROGATE:
         break;
   }

   if (!SetServiceStatus (svcStatusHnd,  &svcStatus))
   {
      status = GetLastError();
// error msg
   }
   return;
}
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax »

although your post is already a few months old: Thanks, quite useful =D>
Exhumer
Earned a small fee
Earned a small fee
Posts: 10
Joined: Thu Jun 22, 2006 2:31 pm
Location: Odessa, Ukraine

Post by Exhumer »

I've implemented Windows service according to viraptor's template. Additionally I've to override OnRun method of wxApp. And found that OnRun is never called at all, then my application is running as service. Any idea?
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia »

Exhumer wrote:I've implemented Windows service according to viraptor's template. Additionally I've to override OnRun method of wxApp. And found that OnRun is never called at all, then my application is running as service. Any idea?
You can call the OnRun method from at the top of the OnInit function:

Code: Select all

wxTheApp->OnRun()
Also why you need to override this method?
zengo
In need of some credit
In need of some credit
Posts: 7
Joined: Thu May 10, 2007 11:05 am
Location: Netherlands
Contact:

Post by zengo »

priyank_bolia wrote:
Exhumer wrote:I've implemented Windows service according to viraptor's template. Additionally I've to override OnRun method of wxApp. And found that OnRun is never called at all, then my application is running as service. Any idea?
You can call the OnRun method from at the top of the OnInit function:

Code: Select all

wxTheApp->OnRun()
Also why you need to override this method?

hi priyank do u have a sample of it compiled cause i trying to compile it
but it don't work by me
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia »

http://priyank.co.in/downloads/wxWin32Service.7z
Added unicode support...
Disclamatory warning: I had just compiled the above code, haven't tested whether it works on not.
zengo
In need of some credit
In need of some credit
Posts: 7
Joined: Thu May 10, 2007 11:05 am
Location: Netherlands
Contact:

Post by zengo »

ok thanks i going to try it out :lol:
zengo
In need of some credit
In need of some credit
Posts: 7
Joined: Thu May 10, 2007 11:05 am
Location: Netherlands
Contact:

Post by zengo »

priyank_bolia wrote:http://priyank.co.in/downloads/wxWin32Service.7z
Added unicode support...
Disclamatory warning: I had just compiled the above code, haven't tested whether it works on not.
hi priyank

i try to compile it but i getting linking errors very strange these ones i getting :

------ Build started: Project: wxWin32Service, Configuration: Release Win32 ------
Linking...
win32service.obj : error LNK2019: unresolved external symbol "wchar_t const * const wxEmptyString" (?wxEmptyString@@3PB_WB) referenced in function "protected: void __thiscall wxStringBase::Init(void)" (?Init@wxStringBase@@IAEXXZ)
win32service.obj : error LNK2019: unresolved external symbol "protected: void __thiscall wxStringBase::InitWith(wchar_t const *,unsigned int,unsigned int)" (?InitWith@wxStringBase@@IAEXPB_WII@Z) referenced in function "public: __thiscall wxStringBase::wxStringBase(wchar_t const *)" (??0wxStringBase@@QAE@PB_W@Z)
win32service.obj : error LNK2019: unresolved external symbol "public: int __thiscall wxString::Cmp(wchar_t const *)const " (?Cmp@wxString@@QBEHPB_W@Z) referenced in function "bool __cdecl operator==(class wxString const &,wchar_t const *)" (??8@YA_NABVwxString@@PB_W@Z)
win32service.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall wxApp::Initialize(int &,wchar_t * *)" (?Initialize@wxApp@@UAE_NAAHPAPA_W@Z)
win32service.obj : error LNK2019: unresolved external symbol "public: int __thiscall wxString::Find(wchar_t const *)const " (?Find@wxString@@QBEHPB_W@Z) referenced in function _WinMain@16
win32service.obj : error LNK2019: unresolved external symbol "public: static class wxString __cdecl wxString::Format(wchar_t const *,...)" (?Format@wxString@@SA?AV1@PB_WZZ) referenced in function _WinMain@16
wxbase28u.lib(baselib_log.obj) : error LNK2019: unresolved external symbol __iob referenced in function "public: __thiscall wxLogStderr::wxLogStderr(struct _iobuf *)" (??0wxLogStderr@@QAE@PAU_iobuf@@@Z)
wxbase28u.lib(baselib_msgout.obj) : error LNK2001: unresolved external symbol __iob
wxbase28u.lib(baselib_datetime.obj) : error LNK2019: unresolved external symbol _timezone referenced in function "int __cdecl GetTimeZone(void)" (?GetTimeZone@@YAHXZ)
OLDNAMES.lib(timezone.obj) : error LNK2001: unresolved external symbol _timezone
OLDNAMES.lib(timezone.obj) : error LNK2001: unresolved external symbol __timezone
Release/wxWin32Service.exe : fatal error LNK1120: 9 unresolved externals
Build log was saved at "file://c:\Documents and Settings\SeNeR\Desktop\wxWin32Service\wxWin32Service\wxWin32Service\Release\BuildLog.htm"
wxWin32Service - 12 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia »

Are you using the solution creation by mine or you created your own.
Also please mention compiler version while mentioning compilation issues.

Did you turned off Unicode in the setup.h file, and also did you build the unicode wxWidgets libraries.

Also did you edit any project settings. Please post the project command line compilations options.
zengo
In need of some credit
In need of some credit
Posts: 7
Joined: Thu May 10, 2007 11:05 am
Location: Netherlands
Contact:

Post by zengo »

I using your solution and the program i using is visual studio 2005.
In the setup.h file the unicode is set to 0 i didn't change nothing in it and
i installed the wxwidget with wxpack program i think it does build everything let me know if i wrong these are the errors i getting

Error 1 error LNK2019: unresolved external symbol "wchar_t const * const wxEmptyString" (?wxEmptyString@@3PB_WB) referenced in function "protected: void __thiscall wxStringBase::Init(void)" (?Init@wxStringBase@@IAEXXZ) win32service.obj
Error 2 error LNK2019: unresolved external symbol "protected: void __thiscall wxStringBase::InitWith(wchar_t const *,unsigned int,unsigned int)" (?InitWith@wxStringBase@@IAEXPB_WII@Z) referenced in function "public: __thiscall wxStringBase::wxStringBase(wchar_t const *)" (??0wxStringBase@@QAE@PB_W@Z) win32service.obj
Error 3 error LNK2019: unresolved external symbol "public: int __thiscall wxString::Cmp(wchar_t const *)const " (?Cmp@wxString@@QBEHPB_W@Z) referenced in function "bool __cdecl operator==(class wxString const &,wchar_t const *)" (??8@YA_NABVwxString@@PB_W@Z) win32service.obj
Error 4 error LNK2001: unresolved external symbol "public: virtual bool __thiscall wxApp::Initialize(int &,wchar_t * *)" (?Initialize@wxApp@@UAE_NAAHPAPA_W@Z) win32service.obj
Error 5 error LNK2019: unresolved external symbol "public: int __thiscall wxString::Find(wchar_t const *)const " (?Find@wxString@@QBEHPB_W@Z) referenced in function _WinMain@16 win32service.obj
Error 6 error LNK2019: unresolved external symbol "public: static class wxString __cdecl wxString::Format(wchar_t const *,...)" (?Format@wxString@@SA?AV1@PB_WZZ) referenced in function _WinMain@16 win32service.obj
Error 7 error LNK2019: unresolved external symbol __iob referenced in function "public: __thiscall wxLogStderr::wxLogStderr(struct _iobuf *)" (??0wxLogStderr@@QAE@PAU_iobuf@@@Z) wxbase28u.lib
Error 8 error LNK2001: unresolved external symbol __iob wxbase28u.lib
Error 9 error LNK2019: unresolved external symbol _timezone referenced in function "int __cdecl GetTimeZone(void)" (?GetTimeZone@@YAHXZ) wxbase28u.lib
Error 10 error LNK2001: unresolved external symbol _timezone OLDNAMES.lib
Error 11 error LNK2001: unresolved external symbol __timezone OLDNAMES.lib
Error 12 fatal error LNK1120: 9 unresolved externals Release/wxWin32Service.exe

maybe it little problem that i don't know
RJP Computing
Experienced Solver
Experienced Solver
Posts: 75
Joined: Sat Dec 10, 2005 10:38 pm
Location: Michigan, USA
Contact:

Post by RJP Computing »

You need to make sure that you set the project setting "Configuration Properties->C/C++->Language->Treat wchar_t as a Built-in Type" to "No" for proper compatibility with wxPack.
- Ryan
RJP Computing
wxPack - Precompiled wxWidgets package.

Ubuntu 9.04 x86_64/WinXP, AMD Athlon x2 3000+, 4000MB RAM, AC 97 Audio, nVidia GeForce 9400GS 1GB
jb_coder
Super wx Problem Solver
Super wx Problem Solver
Posts: 267
Joined: Mon Oct 18, 2004 10:55 am

Post by jb_coder »

Another option is using something like the Poco libraries (http://www.appinf.com/poco/info/index.html). The library works well with wxWidgets and provides classes like Poco:::Util::ServerApplication which allow your program to run as a Windows service or Unix daemon.
zengo
In need of some credit
In need of some credit
Posts: 7
Joined: Thu May 10, 2007 11:05 am
Location: Netherlands
Contact:

Post by zengo »

RJP Computing wrote:You need to make sure that you set the project setting "Configuration Properties->C/C++->Language->Treat wchar_t as a Built-in Type" to "No" for proper compatibility with wxPack.
i set it to no now i getting less error thank you do know maybe how resolve these ones>>

Error 1 error LNK2019: unresolved external symbol __iob referenced in function "public: __thiscall wxLogStderr::wxLogStderr(struct _iobuf *)" (??0wxLogStderr@@QAE@PAU_iobuf@@@Z) wxbase28u.lib
Error 2 error LNK2001: unresolved external symbol __iob wxbase28u.lib
Error 3 error LNK2019: unresolved external symbol _timezone referenced in function "int __cdecl GetTimeZone(void)" (?GetTimeZone@@YAHXZ) wxbase28u.lib
Error 4 error LNK2001: unresolved external symbol _timezone OLDNAMES.lib
Error 5 error LNK2001: unresolved external symbol __timezone OLDNAMES.lib
Error 6 fatal error LNK1120: 3 unresolved externals Release/wxWin32Service.exe
zengo
In need of some credit
In need of some credit
Posts: 7
Joined: Thu May 10, 2007 11:05 am
Location: Netherlands
Contact:

Post by zengo »

wxbase28u.lib is in additional dependencies but i still getting errors
any hints or tips what i must do
priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia »

zengo wrote:wxbase28u.lib is in additional dependencies but i still getting errors
any hints or tips what i must do
I have no idea about wxPack, you can try building the wxWidgets libraries yourself from the source code.

Try with Multi-Threaded instead of Multi-Threaded DLL in C++ options or with Single threaded.
Some people use that, I don't have any idea what wxPACK uses, but with the wxWidgets source and libraries, the project runs fine at my end. I don't see any problem in that. Its part of now wxVS2005Integration also.
Post Reply