Has anybody here experience with running wt inside a Windows Service?
I started playing around with Wt::WServer, but then I realized that
dealing with Windows Services natively is a lot harder then it used to
be when I worked with Borland's C++ Builder.
So, I based my work on the "Service Framework Library for Native Windows
Service Applications" from
http://www.codeguru.com/cpp/w-p/system/services/article.php/c14503__2/
At the moment, the service starts, but connecting to it's port doesn't
create a new application instance, and thus leads to a timeout in the
browser.
Also what is not sactisfactory at the moment is that I have to pass the
arguments everytime I start the service.
So my main question is, if someone already went through all this, and if
not if people here would be interested in the solution in the form of a
Wt::WWindowsService class or a wiki documentation.

So here are the interesting parts:
// service_testrun.bat : 
        sc.exe create Nightly binPath= "C:\PL_VC8\Installer\NightlyBuildSuccess
\bin\Release\NightlyBuildSuccessService.exe"
        sc.exe start Nightly --docroot "C:\PL_VC8\Installer\NightlyBuildSuccess
\res" --http-address 0.0.0.0 --http-port 8080 --config "C:\PL_VC8
\Installer\NightlyBuildSuccess\wt_config.xml"
        pause
        sc.exe stop Nightly
        sc.exe delete Nightly
        
// gives me the following log : 
2009-Apr-08 10:16:27 initializing
2009-Apr-08 10:16:27   -> Nightly
2009-Apr-08 10:16:27   -> --docroot
2009-Apr-08 10:16:27   -> C:\PL_VC8\Installer\NightlyBuildSuccess\res
2009-Apr-08 10:16:27   -> --http-address
2009-Apr-08 10:16:27   -> 0.0.0.0
2009-Apr-08 10:16:27   -> --http-port
2009-Apr-08 10:16:27   -> 8080
2009-Apr-08 10:16:27   -> --config
2009-Apr-08 10:16:27   -> C:\PL_VC8\Installer\NightlyBuildSuccess
\wt_config.xml
2009-Apr-08 10:16:27 Service started
2009-Apr-08 10:27:33 Service stopped
        
        
// main entry point of the application
#ifndef _WIN_SERVICE_
int main(int argc, char *argv[])
{
        return Wt::WRun(argc, argv, &createApplication);
}
#else

#define IDS_WT_WIN_SERVICE              101

SFL_BEGIN_SERVICE_MAP(CSimpleServiceApp)
        SFL_SERVICE_ENTRY(WWindowsService<BuildSuccessApp>, IDS_WT_WIN_SERVICE)
SFL_END_SERVICE_MAP()

#endif

// WWindowsService header file : 

#ifndef WT_WWINDOWSSERVICE_INCLUDED
#define WT_WWINDOWSSERVICE_INCLUDED

#include "SflBase.h"
#include <ioevent.h>
#include <Dbt.h>
#include <iomanip>
#include <Wt/WServer>
#include <Wt/WApplication>
#include <Wt/WEnvironment>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>


template<class WtApplicationT>
class WWindowsService : public
CServiceBaseT<WWindowsService<WtApplicationT>, SERVICE_ACCEPT_STOP>
{
        SFL_DECLARE_SERVICECLASS_FRIENDS(WWindowsService)

        SFL_BEGIN_CONTROL_MAP_EX(WWindowsService)
                SFL_HANDLE_CONTROL_STOP()
        SFL_END_CONTROL_MAP_EX()

        static void log(const std::string &msg)
        {
        boost::filesystem::ofstream
ofs(boost::filesystem::path(getenv("TEMP")) / "WWindowsService.log",
std::ios_base::app);
        ofs << boost::posix_time::second_clock::local_time() << " " <<
msg << std::endl;
        }

        DWORD OnStop(DWORD& dwWin32Err, DWORD& dwSpecificErr, BOOL& bHandled)
        {
        wtsrv_->stop();

        log("Service stopped");

        bHandled =  TRUE;
        return SERVICE_STOPPED;
    }



#if defined(_MSC_VER) && (_MSC_VER < 1300)
public:
#endif
        LPVOID GetServiceContext() { return this; }

        BOOL InitInstance(DWORD dwArgc, LPTSTR* lpszArgv, DWORD& dwSpecificErr)
        {
        try
        {
            log("initializing");
            for(int i=0; i<dwArgc; ++i)
                log(string("  -> ") + lpszArgv[i]);

            delete wtsrv_;
            wtsrv_ = new Wt::WServer(lpszArgv[0]);

            // WTHTTP_CONFIGURATION is e.g. "/etc/wt/wthttpd"
            wtsrv_->setServerConfiguration(dwArgc, lpszArgv,
WTHTTP_CONFIGURATION);

            // add a single entry point, at the default location (as
determined
            // by the server configuration's deploy-path)
            wtsrv_->addEntryPoint(Wt::WServer::Application,
&WWindowsService::createApplication);
            wtsrv_->start();

            log("Service started");

        }
        catch(Wt::WServer::Exception& e)
        {
            std::cerr << e.what() << "\n";
            log(e.what());
            return FALSE;
        }
        catch (std::exception& e)
        {
            std::cerr << "exception: " << e.what() << "\n";
            log(e.what());
            return FALSE;
        }

        return TRUE;
        }

        WWindowsService() : wtsrv_(NULL) {};
        virtual ~WWindowsService() { delete wtsrv_; };

private:

    // callback function is called everytime when a user enters the
page. Can be used to authenticate.
    static Wt::WApplication *createApplication(const Wt::WEnvironment&
env)
    {
        log("creating application");

        WtApplicationT *wtapp = new WtApplicationT(env);

        log("application created");

        return wtapp;
    }

    Wt::WServer *wtsrv_;
};
#endif


------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
_______________________________________________
witty-interest mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/witty-interest

Reply via email to