<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Starten von Programmen aus einem Service ...]]></title><description><![CDATA[<p>Hallo,</p>
<p>nachdem ich nun einen Service erzeugen konnte,<br />
habe ich das Shellexecute ausprobiert und festgestellt, das<br />
dieses aus einem Service heraus keine Wirkung hat <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /><br />
Wie macht man es dann ?<br />
Es geht praktisch darum, das man OHNE eingeloggt zu sein<br />
ein Programm mit einem Benutzerkonto starten kann.<br />
Oder so ähnlich ...</p>
<p>mfg<br />
thenoname</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/88840/starten-von-programmen-aus-einem-service</link><generator>RSS for Node</generator><lastBuildDate>Tue, 21 Apr 2026 16:53:07 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/88840.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 13 Oct 2004 15:46:39 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Starten von Programmen aus einem Service ... on Wed, 13 Oct 2004 15:46:39 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>nachdem ich nun einen Service erzeugen konnte,<br />
habe ich das Shellexecute ausprobiert und festgestellt, das<br />
dieses aus einem Service heraus keine Wirkung hat <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /><br />
Wie macht man es dann ?<br />
Es geht praktisch darum, das man OHNE eingeloggt zu sein<br />
ein Programm mit einem Benutzerkonto starten kann.<br />
Oder so ähnlich ...</p>
<p>mfg<br />
thenoname</p>
]]></description><link>https://www.c-plusplus.net/forum/post/627953</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/627953</guid><dc:creator><![CDATA[thenoname]]></dc:creator><pubDate>Wed, 13 Oct 2004 15:46:39 GMT</pubDate></item><item><title><![CDATA[Reply to Starten von Programmen aus einem Service ... on Fri, 15 Oct 2004 07:25:37 GMT]]></title><description><![CDATA[<p>Teste mal eine der Beiden Funktionen aus folgender Datei (code in ne .h datei speichern un din Projekt einbilden) ... in meinen Service funktionierts so ...<br />
hab diese Funktionen mal von <a href="http://www.codeguru.com" rel="nofollow">www.codeguru.com</a> geloadet ... hab sie also nicht selbst geschrieben! (damit keiner denkt ich würd code stehlen und ihn für meinen ausgeben ) ...</p>
<pre><code>#include &quot;windows.h&quot;
#include &lt;process.h&gt;

BOOL RunProcessAndForget(CString sCmdLine,
                         CString sRunningDir,
                         int *nRetValue);

BOOL RunProcessAndWait(CString sCmdLine, 
                       CString sRunningDir, 
                       int *nRetValue);

//---------------------------------------------------------
// Run a synchronized other command line EXE. Returns only 
// after this exits. The process is runned as a console window.
// Returns Values : TRUE if the process was created
//                  FALSE if not.
// see *nRetValue for the LastError number
BOOL RunProcessAndWait(CString sCmdLine, 
                       CString sRunningDir, 
                       int *nRetValue)
{
 int nRetWait;
 int nError;

 // That means wait 300 s before returning an error
 // You can change it to the value you need.
 // If you want to wait for ever just use 'dwTimeout = INFINITE'&gt;
 DWORD dwTimeout = 1000 *300; 

 STARTUPINFO stInfo;
 PROCESS_INFORMATION prInfo;
 BOOL bResult;
 ZeroMemory( &amp;stInfo, sizeof(stInfo) );
 stInfo.cb = sizeof(stInfo);
 stInfo.dwFlags=STARTF_USESHOWWINDOW;
 stInfo.wShowWindow=SW_MINIMIZE;

 bResult = CreateProcess(NULL, 
                         (LPSTR)(LPCSTR)sCmdLine, 
                         NULL, 
                         NULL, 
                         TRUE,
                         CREATE_NEW_CONSOLE 
                         | NORMAL_PRIORITY_CLASS,
                         NULL,
                         (LPCSTR)sRunningDir,
                         &amp;stInfo, 
                         &amp;prInfo);
 *nRetValue = nError = GetLastError();

 if (!bResult) return FALSE;
  nRetWait =  WaitForSingleObject(prInfo.hProcess,dwTimeout);

 CloseHandle(prInfo.hThread); 
 CloseHandle(prInfo.hProcess); 

 if (nRetWait == WAIT_TIMEOUT) return FALSE;
  return TRUE;
}
//---------------------------------------------------------
// This function call a command line process.
// Returns Values : TRUE if the process was created
//                  FALSE if not.
// see *nRetValue for the LastError number
BOOL RunAndForgetProcess(CString sCmdLine,
                         CString sRunningDir,
                         int *nRetValue)
{
 int nRetWait;
 int nError;
 STARTUPINFO stInfo;
 PROCESS_INFORMATION prInfo;
 BOOL bResult;
 ZeroMemory( &amp;stInfo, sizeof(stInfo) );
 stInfo.cb = sizeof(stInfo);
 stInfo.dwFlags=STARTF_USESHOWWINDOW;
 stInfo.wShowWindow=SW_MINIMIZE;

 bResult = CreateProcess(NULL, 
                         (LPSTR)(LPCSTR)sCmdLine, 
                         NULL, 
                         NULL, 
                         TRUE,
                         CREATE_NEW_CONSOLE 
                         | NORMAL_PRIORITY_CLASS ,
                         NULL,
                         (LPCSTR)sRunningDir ,
                         &amp;stInfo, 
                         &amp;prInfo);
 *nRetValue = nError = GetLastError();

 // Don't write these two lines if you need
 CloseHandle(prInfo.hThread); 

 class=&quot;codeComment&quot;&gt;// to use these handles
 CloseHandle(prInfo.hProcess);

 if (!bResult) return FALSE;
  return TRUE;	
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/629142</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/629142</guid><dc:creator><![CDATA[Kingrabbit]]></dc:creator><pubDate>Fri, 15 Oct 2004 07:25:37 GMT</pubDate></item><item><title><![CDATA[Reply to Starten von Programmen aus einem Service ... on Fri, 15 Oct 2004 19:01:00 GMT]]></title><description><![CDATA[<p>Ja,<br />
die CreateProcess habe ich nun auch verwendet ...<br />
Klappt gut, auch ohne weitere Prameter. Die zwei letzten<br />
Strukturen sind bei mir mit zero gefüllt, dürfen aber nicht<br />
NULL sein.<br />
Habe allerdings festgestellt, das bei fehlender Datei es einen<br />
Crash des Services gibt ...<br />
Nun kann ich also ohne logon Programme starten, wenn ich eine<br />
Joysticktaste drücke. (naja, wers halt braucht)</p>
<p>Desweiteren gibt es noch CreatProcessWithLogonW und CreateProcessAsUser.<br />
Die sind allerdings erst ein Studium wert, um Nutzen ziehen zu können.</p>
<p>Danke für den Code ...<br />
thenoname</p>
]]></description><link>https://www.c-plusplus.net/forum/post/629727</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/629727</guid><dc:creator><![CDATA[thenoname response]]></dc:creator><pubDate>Fri, 15 Oct 2004 19:01:00 GMT</pubDate></item><item><title><![CDATA[Reply to Starten von Programmen aus einem Service ... on Mon, 18 Oct 2004 13:12:21 GMT]]></title><description><![CDATA[<p>Freut mich, dass ich Dir helfen konnte,<br />
aber wollte mal fragen, ob Du auf folgendes Problem, was ich grad habe ne antwort hast:</p>
<p>Ich bastle grad einen Service ... hat bis jetzt auch gut geklappt, wollte<br />
jetzt allerdings ein Client Programm schreiben was den Service Verwaltet (Einstellungen ändert usw.) deshalb hab ich eine CAsyncSocket klasse geschrieben. ich hab die Klasse in einer &quot;normalen&quot; Dialogfeld Anwendung getestet, sie funktioniert einwandfrei (is nur zum test, die sendet wenn man irgendwas an sie sendet einfach ein &quot;hallo&quot; zurück, dieser Send befehl steht inder überschriebenen OnReceive Funktion) , wenn ich diese Klasse aber in dem Service Einbinde kann man zwar connecten, aber die überschriebene OnAccept Funktion wird nie ausgeführt, wodurch man ja nich richtig connectet ist ... ich hab die Vermutung, dass in einen Service solche ereignisse, wie Connecting und Receive nicht augelöst werden, oder liege ich da falsch ?!? (hab bis jetzt mit Services keine Erfahrung, und mit Sockets nur nen bisschen *g* ) ...</p>
<p>hab das schon allgemein als Thema gepostet, hat noch keiner geantwortet, aber ich dachte du hättest vielleich davon Ahnung ????!!!!??? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/631577</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/631577</guid><dc:creator><![CDATA[Kingrabbit]]></dc:creator><pubDate>Mon, 18 Oct 2004 13:12:21 GMT</pubDate></item><item><title><![CDATA[Reply to Starten von Programmen aus einem Service ... on Mon, 18 Oct 2004 17:52:17 GMT]]></title><description><![CDATA[<p>post mal den code den du bis her hast!<br />
dann können wir besser analysieren!</p>
<p>cu</p>
]]></description><link>https://www.c-plusplus.net/forum/post/631873</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/631873</guid><dc:creator><![CDATA[acer]]></dc:creator><pubDate>Mon, 18 Oct 2004 17:52:17 GMT</pubDate></item><item><title><![CDATA[Reply to Starten von Programmen aus einem Service ... on Wed, 20 Oct 2004 12:01:57 GMT]]></title><description><![CDATA[<p>ja ich poste erst mal nen Teil .. is nämlich viel .... ich glaub dass es daran liegt, dass so was wie die MessageMap von nen &quot;normalen&quot; Windows Programmen dort fehlt (is aber nur so ne Vermutung ... ich bin nich soo der Held, was WinAPI Programmierung angeht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /> ) ... aber hier erst mal der Code:</p>
<p>erstmal die Socketklasse:</p>
<pre><code>#if !defined(AFX_MYSOCKET_H__72590960_C463_4A50_9FE6_B08F623A9D3D__INCLUDED_)
#define AFX_MYSOCKET_H__72590960_C463_4A50_9FE6_B08F623A9D3D__INCLUDED_

#if _MSC_VER &gt; 1000
#pragma once
#endif // _MSC_VER &gt; 1000
// MySocket.h : header file

class CMySocket : public CAsyncSocket
{
// Attributes
public:

// Operations
public:
	CMySocket();
	virtual ~CMySocket();

	//CListBox* Out;

	CMySocket* So1;
	CMySocket* So2;
	CMySocket* So3;

// Overrides
public:
	void SetParent(CDialog* pWnd);
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CMySocket)
	//}}AFX_VIRTUAL

	// Generated message map functions
	//{{AFX_MSG(CMySocket)
		// NOTE - the ClassWizard will add and remove member functions here.
	//}}AFX_MSG

// Implementation
protected:
	void OnReceive(int nErrorCode);
	void OnSend(int nErrorCode);
	void OnClose(int nErrorCode);
	void OnConnect(int nErrorCode);
	void OnAccept(int nErrorCode);
private:
	CDialog* m_pWnd;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MYSOCKET_H__72590960_C463_4A50_9FE6_B08F623A9D3D__INCLUDED_)
</code></pre>
<pre><code>// MySocket.cpp : implementation file
//

#include &quot;stdafx.h&quot;
//#include &quot;sock.h&quot;
#include &quot;MySocket.h&quot;
//#include &quot;SockDlg.h&quot;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMySocket

CMySocket::CMySocket()
{
//	Out = NULL;
	So1 = NULL;
	So2 = NULL;
	So3 = NULL;
}

CMySocket::~CMySocket()
{
}

// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CMySocket, CAsyncSocket)
	//{{AFX_MSG_MAP(CMySocket)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/////////////////////////////////////////////////////////////////////////////
// CMySocket member functions

void CMySocket::SetParent(CDialog *pWnd)
{
// Elementzeiger setzen
     m_pWnd = pWnd;
}

void CMySocket::OnAccept(int nErrorCode)
{
 // Sind Fehler aufgetreten?
 //    if (nErrorCode == 0)
         // Nein, OnAccept-Funktion des Dialogfelds aufrufen
//          ((CSockDlg*)m_pWnd)-&gt;OnAccept();
	//So2 = new CMySocket;
//	if(So1-&gt;Accept(*So2)) Out-&gt;AddString(&quot;Accept&quot;);
	So1-&gt;Accept(*So2);

}

void CMySocket::OnConnect(int nErrorCode)
{
// Sind Fehler aufgetreten?
     if (nErrorCode == 0)
	 {
		 //Out-&gt;AddString(&quot;Connected&quot;);
	 }
         // Nein, OnAccept-Funktion des Dialogfelds aufrufen
  //        ((CSockDlg*)m_pWnd)-&gt;OnConnect();
}

void CMySocket::OnClose(int nErrorCode)
{
// Sind Fehler aufgetreten?
     if (nErrorCode == 0)
	 {
	//	 Out-&gt;AddString(&quot;Disconnected&quot;);
		 So2-&gt;Close();
		 //So1-&gt;Listen();
	 }
}

void CMySocket::OnSend(int nErrorCode)
{
// Sind Fehler aufgetreten?
//     if (nErrorCode == 0)
         // Nein, OnAccept-Funktion des Dialogfelds aufrufen
//          ((CSockDlg*)m_pWnd)-&gt;OnSend();
}

void CMySocket::OnReceive(int nErrorCode)
{
// Sind Fehler aufgetreten?
//     if (nErrorCode == 0)
         // Nein, OnAccept-Funktion des Dialogfelds aufrufen
//          ((CSockDlg*)m_pWnd)-&gt;OnReceive();

	char Buff[1024];
	int i;

	if (nErrorCode == 0)
	{
		if(So2 == NULL)  return;
		i = So2-&gt;Receive(Buff, 512);
		Buff[i] = 0;
		//Out-&gt;AddString(Buff);
	}

	strcpy(Buff, &quot;Hallo Welt !!!&quot;);
	So2-&gt;Send(Buff, strlen(Buff));

	//Out-&gt;AddString(&quot;sdsssss&quot;);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/633255</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/633255</guid><dc:creator><![CDATA[Kingrabbit]]></dc:creator><pubDate>Wed, 20 Oct 2004 12:01:57 GMT</pubDate></item><item><title><![CDATA[Reply to Starten von Programmen aus einem Service ... on Wed, 20 Oct 2004 12:03:50 GMT]]></title><description><![CDATA[<p>und jetzt noch die Endlosschleife, die mein Service ausführt:</p>
<pre><code>void EndlessLoop()
{
//	Output(&quot;EndlessLoop Start\n&quot;);

	SYSTEMTIME Clock;
	CString Out;
	HANDLE hTimer;
	bool StartSock = true;
	CMySocket Sock;
	CMySocket Sock2;

	hTimer = ::CreateWaitableTimer(0, FALSE, &quot;DemoService-Timer&quot;);

	// This endlessloop is killed by Windows when the service is stopped or shutdown
	while (1)
	{
		if (hTimer != 0)
		{
			LARGE_INTEGER Elapse;
			Elapse.QuadPart = -10000000; // 1 Seconds in 100 Nanoseconds resolution (negative=relative)
			BOOL Res = ::SetWaitableTimer(hTimer, &amp;Elapse, 0, 0, 0, TRUE);

			if (Res)
			{
				DWORD Event = WaitForSingleObject(hTimer, 300000); // 30 seconds timeout
				// Event = (258=WAIT_TIMEOUT) (128=WAIT_ABANDONED) (0=WAIT_OBJECT_0) (0xFFFFFFFF=WAIT_FAILED)
			}
		}

		::GetLocalTime(&amp;Clock);
//############################################################################		
//############################################################################
//############################################################################

	CFtpGet ftp;
	List Commands;
	char LogBuff[3000];
	char CTemp[512];
//	char Time[16];
//	CString CTime;
//	CString CSetTime;
	CString JobTime;
	CString RealTime;
	CString JobDate;
	CString RealDate;
	bool Run = false;
	unsigned int JobCount;
	unsigned int i = 0;
	Job* JobSet;

/*	_strtime(Time);
	CTime = Time;
	CSetTime = g_Service.Settings.StartTime;
	CTime = CTime.Mid(0, 8);
	CSetTime = CSetTime.Mid(0, 8);*/

	if(StartSock == true)
	{
		Sock.So1 = &amp;Sock;
		Sock.So2 = &amp;Sock2;

		Sock2.So1 = &amp;Sock;
		Sock2.So2 = &amp;Sock2;

		Sock.Create(4000);
		Sock.Listen();

		StartSock = false;
	}

	JobCount = g_Service.JobList.GetCount();

	char ww[16];
	_itoa( JobCount, ww, 10 );// wandelt int in char um

	while(i &lt; JobCount)
	{
		JobSet = (Job*)g_Service.JobList.GetPoint(i, false);
		JobDate = JobSet-&gt;StartDate;
		JobTime = JobSet-&gt;StartTime;

		//_strdate(CTemp);
		GetDate(CTemp);
		RealDate = CTemp;
		_strtime(CTemp);
		RealTime = CTemp;

		Run = false;
		if(DateABiggerDateB(RealDate, JobDate) == true)
		{
			if(TimeABiggerTimeB(RealTime, JobTime) == true) Run = true;
		}

		i++;
		if(Run == true)
		{
			Commands.DelAll();
			Commands.SetSize(2048);

			if(FileExist(JobSet-&gt;ComFile) == false)
			{
				Log(&quot;ERROR!!! Command  - File do not exist or unable to open !!!&quot;, true);
				return;
			}

			Log(&quot;\r\n&quot;, false);
			Log(&quot;\r\n&quot;, false);
			strcpy(LogBuff, &quot;Job starting with Commandfile: &quot;);
			strcat(LogBuff, JobSet-&gt;ComFile);
			Log(LogBuff, true);

			ExecuteSkript(JobSet-&gt;ComFile, &amp;Commands, &amp;ftp);

			Log(&quot;Job Finish&quot;, true);
			DelOrReBuildJob(i-1, &amp;g_Service.JobList);
			i = 0;
			JobCount = g_Service.JobList.GetCount();
		}
	}
//############################################################################
//############################################################################
//############################################################################

	};
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/633258</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/633258</guid><dc:creator><![CDATA[Kingrabbit]]></dc:creator><pubDate>Wed, 20 Oct 2004 12:03:50 GMT</pubDate></item><item><title><![CDATA[Reply to Starten von Programmen aus einem Service ... on Wed, 20 Oct 2004 12:06:00 GMT]]></title><description><![CDATA[<p>und noch die Service Klasse:</p>
<pre><code>// cService.h: interface for the cService class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CSERVICE_H__FD1A6E41_AAFB_11D7_A8B4_000AE637F271__INCLUDED_)
#define AFX_CSERVICE_H__FD1A6E41_AAFB_11D7_A8B4_000AE637F271__INCLUDED_

#if _MSC_VER &gt; 1000
#pragma once
#endif // _MSC_VER &gt; 1000

#include &quot;winsvc.h&quot;

class cService  
{
public:
	cService();
	virtual ~cService();

	DWORD Start();
	DWORD Stop();
	DWORD Create();
	DWORD Delete();

	void Dispatch();
	void MainStart   (DWORD argc, LPTSTR *argv);
	void ControlHandler (DWORD Opcode);

	Set Settings;
	List JobList;
	AppPathStr AppPathSt;
	bool Running;
private:

	SERVICE_STATUS_HANDLE  hdlStat;

};

#endif // !defined(AFX_CSERVICE_H__FD1A6E41_AAFB_11D7_A8B4_000AE637F271__INCLUDED_)
</code></pre>
<pre><code>// cService.cpp: implementation of the cService class.
//
//////////////////////////////////////////////////////////////////////

#include &quot;stdafx.h&quot;
#include &quot;Service.h&quot;
#include &quot;cService.h&quot;

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

extern Set Settings;

// global instance of Service
cService g_Service;

cService::cService()
{
	Running = false;
}

cService::~cService()
{

}
// return Errorcode or 0
// Install the service when user clicks the Create button
DWORD cService::Create()
{
	SC_HANDLE hdlSCM = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);

	CString Calling = ::GetCommandLine();
	Calling += &quot; /Service&quot;;

	if (hdlSCM == 0) return ::GetLastError();

	SC_HANDLE hdlServ = CreateService(
		hdlSCM,                    // SCManager database 
		ServiceName,               // name of service 
		ServiceDisplayName,        // service name to display 
		STANDARD_RIGHTS_REQUIRED,  // desired access 
		SERVICE_WIN32_OWN_PROCESS, // service type 
		SERVICE_DEMAND_START,      // start type 
		SERVICE_ERROR_NORMAL,      // error control type 
		Calling,                   // service's binary Path name
		0,                      // no load ordering group 
		0,                      // no tag identifier 
		0,                      // no dependencies 
		0,                      // LocalSystem account 
		0);                     // no password 

	DWORD Ret = 0;
	if (!hdlServ) Ret = ::GetLastError();
    CloseServiceHandle(hdlServ);
	return Ret;
}

// return Errorcode or 0
// Uninstall the service when user clicks the Delete button
DWORD cService::Delete()
{
	SC_HANDLE hdlSCM = OpenSCManager(0, 0, STANDARD_RIGHTS_REQUIRED);

	if (!hdlSCM) return ::GetLastError();

	SC_HANDLE hdlServ = OpenService(hdlSCM, ServiceName, DELETE);

	DWORD Ret = 0;
	if (!DeleteService(hdlServ)) Ret = ::GetLastError();
	CloseServiceHandle(hdlServ);
	return Ret;
}

// return Errorcode or 0
// Start the service when user clicks the Start button
DWORD cService::Start()
{
	SC_HANDLE hdlSCM = OpenSCManager(0, 0, STANDARD_RIGHTS_REQUIRED);

	if (!hdlSCM) return ::GetLastError();

	SC_HANDLE hdlServ = OpenService(hdlSCM, ServiceName, SERVICE_START);

	DWORD Ret = 0;
	if (!StartService(hdlServ, 0, 0)) Ret = ::GetLastError();
	CloseServiceHandle(hdlServ);
	Running = true;
	return Ret;
}

// return Errorcode or 0
// Stop the service when user clicks the Stop button
DWORD cService::Stop()
{
	SC_HANDLE hdlSCM = OpenSCManager(0, 0, STANDARD_RIGHTS_REQUIRED);

	if (!hdlSCM) return ::GetLastError();

	SC_HANDLE hdlServ = OpenService(hdlSCM, ServiceName, SERVICE_STOP);

	SERVICE_STATUS ServStat;
	DWORD Ret = 0;
	if (!ControlService(hdlServ, SERVICE_CONTROL_STOP, &amp;ServStat)) Ret = ::GetLastError();
	CloseServiceHandle(hdlServ);
	Running = false;
	return Ret;
}

// this function must be in global namespace (Windows API callback)
void ApiServiceMainStarter(DWORD argc, LPTSTR *argv);

void ApiServiceMainStarter(DWORD argc, LPTSTR *argv)
{
	g_Service.MainStart(argc, argv);
} 

// this function must be in global namespace (Windows API callback)
void ApiServiceControlHandler(DWORD Opcode);

void ApiServiceControlHandler(DWORD Opcode)
{
	g_Service.ControlHandler(Opcode);
}

// Service Main Function called by Windows
void cService::MainStart(DWORD argc, LPTSTR *argv)
{
	CString Out = *argv;
	//Output(&quot;Service Main -- Start with Arguments: \&quot;&quot; + Out + &quot;\&quot;&quot;);

	if(!AfxSocketInit())
{
	AfxMessageBox(&quot;Could not initialize Windows Sockets!&quot;);
	return ;
}

    hdlStat = ::RegisterServiceCtrlHandler(ServiceName, (LPHANDLER_FUNCTION) ApiServiceControlHandler);
     if (!hdlStat) 
    { 
		int Err = ::GetLastError();
		Out.Format(&quot;Service Main -- RegisterServiceHandler Error : %d\n&quot;, Err);
		//Output(Out);
        return; 
    } 
	//else Output(&quot;Service Main -- RegisterServiceHandler&quot;);

	ControlHandler (0); // Set status Running

	LoadAppPath(&amp;AppPathSt);

	LoadSettings(&amp;Settings);

	LoadJobs(&amp;JobList);

	EndlessLoop(); // Do the service work (write to logfile every 5 seconds)

	JobList.DelAll();
}

// Start the service (in the Exe which is running as Service!!)
void cService::Dispatch()
{
	SERVICE_TABLE_ENTRY DispTbl[] = 
	{
		{ ServiceName, (LPSERVICE_MAIN_FUNCTION) ApiServiceMainStarter},
		{ 0 , 0}
	}; 

	//Output(&quot;Dispatch -- Before calling StartServiceCtrlDispatcher\n&quot;);

	if (!::StartServiceCtrlDispatcher(DispTbl)) // does not return until service stopped
	{
		int Err = ::GetLastError();
		CString Out;
		Out.Format(&quot;Dispatch -- StartServiceCtrlDispatcher Error : %d\n&quot;, Err);
		//Output(Out);
	}
	//else Output(&quot;Dispatch -- Returning from StartServiceCtrlDispatcher\n&quot;);
}

// Control Handler handles Start / Stop events
void cService::ControlHandler(DWORD Opcode)
{
	SERVICE_STATUS  strctStat;
    strctStat.dwServiceType        = SERVICE_WIN32; 
    strctStat.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    strctStat.dwWin32ExitCode      = NO_ERROR;
    strctStat.dwServiceSpecificExitCode = 0; // returned Status code
    strctStat.dwCheckPoint         = 0;      // returned Error code
    strctStat.dwWaitHint           = 0;

	CString Command, Status;
	if (Opcode == SERVICE_CONTROL_STOP)
	{
		Command = &quot;CONTROL_STOP&quot;;
		strctStat.dwCurrentState = SERVICE_STOPPED;
		Status  = &quot;SERVICE_STOPPED&quot;;		
	}
	else if (Opcode == SERVICE_CONTROL_SHUTDOWN)
	{
		Command = &quot;CONTROL_SHUTDOWN&quot;;
		strctStat.dwCurrentState = SERVICE_STOPPED;
		Status  = &quot;SERVICE_STOPPED&quot;;		
	}
	else if (Opcode == SERVICE_CONTROL_INTERROGATE)
	{
		Command = &quot;CONTROL_INTERROGATE&quot;;
		strctStat.dwCurrentState = SERVICE_RUNNING; 
		Status  = &quot;SERVICE_RUNNING&quot;;		
	}
	else
	{
		Command.Format(&quot;Command Opcode Nr. %d &quot;, Opcode);
		strctStat.dwCurrentState = SERVICE_RUNNING; 	
		Status  = &quot;SERVICE_RUNNING&quot;;
	}

	//if (Opcode != 0) Output(&quot;Control Handler -- received Command &quot;+Command);

    if (!SetServiceStatus (hdlStat, &amp;strctStat)) 
    { 
		int Err = ::GetLastError();
		CString Out;
		Out.Format(&quot;Control Handler -- Set Status Error : %d&quot;, Err);
	//	Output(Out);
        return; 
    } 
	//else Output(&quot;Control Handler -- SetStatus &quot;+Status);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/633261</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/633261</guid><dc:creator><![CDATA[Kingrabbit]]></dc:creator><pubDate>Wed, 20 Oct 2004 12:06:00 GMT</pubDate></item></channel></rss>