Posts mit dem Label C++ werden angezeigt. Alle Posts anzeigen
Posts mit dem Label C++ werden angezeigt. Alle Posts anzeigen

Dienstag, 3. Juli 2012

C++: Create a Windows service

Creating a Windows service is fairly simple. You start by writing you main() function as you would normally. In the main() function you have to call StartServiceCrtlDispatcher(). The programm has to make this call at least 30 seconds after it has launched. Otherwise Windows will assume the service failed to start up. So the simplest main() function for a service will look something like this:

int main(int argc, char **argv) {
  SERVICE_TABLE_ENTRY serviceTable[2];
  serviceTable[0].lpServiceName = "ServiceTest";
  serviceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION) ServiceMain;

  serviceTable[1].lpServiceName = NULL;
  serviceTable[1].lpServiceProc = NULL;
  StartServiceCtrlDispatcher(serviceTable);  
}

StartServiceCrtlDispatcher() takes an array of SERVICE_TABLE_ENTRYs. Each defines the name and callback function of one service it should start. The callback function is run in its own thread and StartServiceCrtlDispatcher() will only return after all services it has started have been stopped.

As the name indicates, the callback function of the service is the real main function of the service. Here the service should do whatever it is supposed to do. In order to by managed by the Services interface of Windows the service has to implement a callback to a control handler with the RegisterServiceCrtlHandler() function. The callback is invoked every time the service should change its state (Stop for example).

The service should use the SetServiceStatus() function to report its current status to the system. The following code can be used as a skeleton for your own service.

SERVICE_STATUS ServiceStatus; 
SERVICE_STATUS_HANDLE hServiceStatus; 

// Control handler function callback
void ControlHandler(DWORD request) 
{ 
  switch(request) { 
    case SERVICE_CONTROL_STOP: 
      // Service has been stopped
      ServiceStatus.dwWin32ExitCode = 0; 
      ServiceStatus.dwCurrentState  = SERVICE_STOPPED; 
      SetServiceStatus (hServiceStatus, &ServiceStatus);
      return; 
 
    case SERVICE_CONTROL_SHUTDOWN: 
      ServiceStatus.dwWin32ExitCode = 0; 
      ServiceStatus.dwCurrentState  = SERVICE_STOPPED; 
      SetServiceStatus (hServiceStatus, &ServiceStatus);
      return; 
        
    default:
      break;
  } 
 
  // Report current status
  SetServiceStatus (ServiceStatusHandle,  &ServiceStatus);
} 

// Service main function callback
void ServiceMain(int argc, char **argv) {
  int count = 0;
  int result;
 
  ServiceStatus.dwServiceType = SERVICE_WIN32; 
  ServiceStatus.dwCurrentState = SERVICE_START_PENDING; 
  ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | 
                                       SERVICE_ACCEPT_SHUTDOWN;
  ServiceStatus.dwWin32ExitCode = 0; 
  ServiceStatus.dwServiceSpecificExitCode = 0; 
  ServiceStatus.dwCheckPoint = 0; 
  ServiceStatus.dwWaitHint = 0; 

  hServiceStatus= RegisterServiceCtrlHandler(
                    "ServiceTest", 
                    (LPHANDLER_FUNCTION) ControlHandler); 
  if (hServiceStatus == (SERVICE_STATUS_HANDLE) 0) { 
    // Registering Control Handler failed
    return; 
  }  

  ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
  SetServiceStatus (hServiceStatus, &ServiceStatus);

  while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) {
    // Do you important service stuff here
    Sleep(5000);
  }
}

This service will run as long as its state is SERVICE_RUNNING. Once the state changes the ServiceMain function will return and the service will terminate.

Visit these links for more examples and explanations:



Donnerstag, 26. April 2012

Shell: Determine lines of code

Use this command to determine the number of lines of code you have written for your C++ project.

find ../src -name "*.cpp" -or -name "*.h" | xargs wc -l

Donnerstag, 23. Februar 2012

C++: string tokenzier

This function splits a string into substrings. It uses a list of delimiter characters to find the boundaries of the substrings.

void tokenize(const std::string &str, 
              std::vector<std::string> &tokens, 
              const std::string &delimiters = " ") {
  string::size_type lastPos = str.find_first_not_of(delimiters, 0);
  string::size_type pos = str.find_first_of(delimiters, lastPos);

  while (std::string::npos != pos || std::string::npos != lastPos) {
    tokens.push_back(str.substr(lastPos, pos - lastPos));
    lastPos = str.find_first_not_of(delimiters, pos);
    pos = str.find_first_of(delimiters, lastPos);
  }
}

Usage:
vector<std::string> tokens;
tokenize("I want to tokenize this!", tokens);

tokenize("2012-02-20", tokens, "-");

Donnerstag, 2. Februar 2012

C++: String trim function

This function removes leading and trailing characters from a string. The default character is a space, but you can use any combination of characters, that should be trimmed.

std::string trim(std::string &str, const std::string &trimChars = " ")
{
  std::string result = str.erase(str.find_last_not_of(trimChars) + 1);
  return result.erase(0, result.find_first_not_of(trimChars));
}

Usage:
string s = trim("Hello World!    ");
std::cout << s;
// prints: Hello World!

s = trim("xxx Hello World! xxx", "x");
std::cout << s;
// prints: Hello World!