Win8上Service程序及外部App调用此Service

论坛 期权论坛     
选择匿名的用户   2021-5-30 01:20   526   0
<h3>一.Service</h3>
<p>借助MSDN上<a href="http://code.msdn.microsoft.com/CppWin7TriggerStartService-8ba5bd5b/sourcecode?fileId&#61;64923&amp;pathId&#61;927862711" rel="noopener noreferrer" target="_blank">Win7 Service的Demo</a>和《<a href="http://blog.csdn.net/lincyang/article/details/6231406" rel="noopener noreferrer" target="_blank">用VC&#43;&#43;建立Service服务应用程序</a>》,在Win8上经历各种磨难,终于跑起来自己改装的服务程序了。</p>
<p>原来API基本没变,我所困惑的是Win7上直接运行都没有问题,在Win8上不可以。</p>
<p>报错:</p>
<pre class="blockcode"><code class="language-plain">OpenSCManager failed w/err 0x00000005</code></pre>
<p>原来是Win8上权限的问题,也许我自己的Win7一启动就拥有了Admin权限吧。</p>
<p><br> </p>
<p>下面直接进入正题,我整合了一下代码,共三个文件:main.c,Service.h, Service.cpp。(项目是控制台程序。)</p>
<p>main.c只是程序的入口,运行时接受参数。</p>
<pre class="blockcode"><code class="language-cpp">#pragma region &#34;Includes&#34;
#include &lt;stdio.h&gt;
#include &lt;windows.h&gt;
#include &#34;Service.h&#34;
#pragma endregion


int wmain(int argc, wchar_t* argv[])
{
if ((argc &gt; 1) &amp;&amp; ((*argv[1] &#61;&#61; L&#39;-&#39; || (*argv[1] &#61;&#61; L&#39;/&#39;))))
{
  if (_wcsicmp(L&#34;install&#34;, argv[1] &#43; 1) &#61;&#61; 0)
  {
   SvcInstall();
  }
  else if (_wcsicmp(L&#34;remove&#34;, argv[1] &#43; 1) &#61;&#61; 0)
  {
   SvcUninstall();
  }
  else if (_wcsicmp(L&#34;query&#34;, argv[1] &#43; 1) &#61;&#61; 0)
  {
   SvcQueryConfig();
  }
        else if(_wcsicmp(L&#34;start&#34;,argv[1] &#43; 1) &#61;&#61; 0)
        {
            SvcStart();
        }
        else if(_wcsicmp(L&#34;stop&#34;,argv[1] &#43; 1) &#61;&#61; 0)
        {
            SvcStopNow();
        }
}
else
{
  _putws(L&#34;Parameters:&#34;);
  _putws(L&#34; -install    to install the service (require admin permission)&#34;);
  _putws(L&#34; -remove     to remove the service (require admin permission)&#34;);
  _putws(L&#34; -query      to query the configuration of the service&#34;);
                _putws(L&#34; -start      to start the service&#34;);
                _putws(L&#34; -stop       to stop the service&#34;);

  RunService();
}

return 0;
}</code></pre>
<p>代码中已经写的很清楚了,我的项目名称为Win8Service,只要运行Win8Service.exe -install,服务就会被安装。</p>
<p><strong>注意:cmd必须要用admin启动。win8下做法:WIN&#43;Q键,打开Search panel,输入cmd,右击Command Prompt,选择Run as administrator。</strong></p>
<p><br> </p>
<p>下面看看这几个函数的实现:</p>
<p>Service.h</p>
<pre class="blockcode"><code class="language-cpp">#pragma once

// Internal name of the service
#define SERVICE_NAME             L&#34;CppWin8Service&#34;

// Displayed name of the service
#define SERVICE_DISPLAY_NAME     L&#34;CppWin8Service Demo&#34;

// List of service dependencies - &#34;dep1\0dep2\0\0&#34;
#define SERVICE_DEPENDENCIES     L&#34;&#34;

// The name of the account under which the service should run
#define SERVICE_ACCOUNT          L&#34;NT AUTHORITY\\LocalService&#34;

// The password to the service account name
#define SERVICE_PASSWORD         NULL

VOID RunService();
VOID SvcInstall();
VOID SvcUninstall();
VOID SvcQueryConfig();
BOOL SvcStart();
VOID SvcStopNow();</code></pre>
<p><br> </p>
<p>Service.cpp</p>
<p></p>
<pre class="blockcode"><code class="language-cpp">#pragma region &#34;Includes&#34;
#include &lt;stdio.h&gt;
#include &lt;windows.h&gt;
#include &#34;Service.h&#34;
#pragma endregion


SERVICE_STATUS          g_ssSvcStatus;         // Current service status
SERVICE_STATUS_HANDLE   g_sshSvcStatusHandle;  // Current service status handle
HANDLE                  g_hSvcStopEvent;


VOID WINAPI SvcMain(DWORD dwArgc, LPWSTR* lpszArgv);
VOID WINAPI SvcCtrlHandler(DWORD dwCtrl);
VOID SvcInit(DWORD dwArgc, LPWSTR* lpszArgv);
VOID SvcStop();
VOID SvcReportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
VOID SvcReportEvent(LPWSTR lpszFunction, DWORD dwErr &#61; 0);


VOID RunService()
{
// You can add any additional services for the process to this table.
SERVICE_TABLE_ENTRY dispatchTable[] &#61;
{
  { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)SvcMain },
  { NULL, NULL }
};

// This call returns when the service has stopped.
// The process should simply terminate when the call returns.
if (!StartServiceCtrlDispatcher(dispatchTable))
{
  SvcReportEvent(L&#34;StartServiceCtrlDispatcher&#34;, GetLastError());
}
}


VOID WINAPI SvcMain(DWORD dwArgc, LPWSTR* lpszArgv)
{
SvcReportEvent(L&#34;Enter SvcMain&#34;);

// Register the handler function for the service
g_sshSvcStatusHandle &#61; RegisterServiceCtrlHandler(SERVICE_NAME,
  SvcCtrlHandler);
if (!g_sshSvcStatusHandle)
{
  SvcReportEvent(L&#34;RegisterServiceCtrlHandler&#34;, GetLastError());
  return;
}

// These SERVICE_STATUS members remain as set here
g_ssSvcStatus.dwServiceType &#61; SERVICE_WIN32_OWN_PROCESS;
g_ssSvcStatus.dwServiceSpecificExitCode &#61; 0;

// Report initial status to the SCM
SvcReportStatus(SERVICE_START_PENDING, NO_ERROR, 3000);

// Perform service-specific initialization and work.
SvcInit(dwArgc, lpszArgv);
}


VOID WINAPI SvcCtrlHandler(DW
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP