早期僅 Visual C++ 能寫 Windows 服務(NT 服務),現 .NET 時代 VB.NET、C# 皆可。但資深 VC++ 開發者若想用 Managed C++,本文提供完整實作指南。
CGNotifier),向導產生繼承 System::ServiceProcess::ServiceBase 的類別public __gc class CGNotifier : public System::ServiceProcess::ServiceBase
{
private:
bool stopping;
int loopsleep; // 毫秒
Threading::Thread* servicethread;
protected:
void OnStart(String* args[])
{
Threading::ThreadStart* threadStart = new Threading::ThreadStart(this, &CGNotifier::mainLoop);
servicethread = new Threading::Thread(threadStart);
servicethread->Start();
}
void mainLoop()
{
loopsleep = 1000; stopping = false;
while (!stopping) { Threading::Thread::Sleep(loopsleep); }
}
void OnStop() { stopping = true; }
};
關鍵點:OnStart 必須快速返回,長時間工作需另闢執行緒(servicethread),OnStop 設旗標通知執行緒結束。
ServiceInstaller、ServiceProcessInstallerServiceProcessInstaller.Account:LocalSystem(預設)、LocalService(Win2003+ 低權限)、NetworkService(需跨機器驗證)ServiceInstaller.StartType:Manual/Automatic/DisabledCGNotifier.exe -Install(而非 InstallUtil,因 C++ 無法產生可驗證代碼)CGNotifier.exe -Install /uapp.config<configuration>
<appSettings>
<add key="runhour" value="22" /> <!-- 22 點執行 -->
</appSettings>
</configuration>
copy app.config $(ConfigurationName)\$(TargetFileName).config
void mainLoop()
{
String* sHour = Configuration::ConfigurationSettings::AppSettings->get_Item("runhour");
int runHour = System::Int32::Parse(sHour);
bool rantoday = false;
stopping = false;
while (!stopping) {
if (DateTime::Now.Hour == runHour && !rantoday) {
// 執行任務:查詢資料庫、刪除過期檔案等
rantoday = true;
} else if (DateTime::Now.Hour != runHour) {
rantoday = false;
}
Threading::Thread::Sleep(loopsleep);
}
}
Diagnostics::EventLog* log;
if (!Diagnostics::EventLog::SourceExists("CGNotifierService"))
Diagnostics::EventLog::CreateEventSource("CGNotifierService", "CGNotifierLog");
log = new Diagnostics::EventLog("CGNotifierLog");
log->Source = "CGNotifierService";
// 任務完成後記錄
log->WriteEntry("服務的運行時間到了。", Diagnostics::EventLogEntryType::Information);
服務無 UI,事件日誌為最佳回報管道,會在事件檢視器建立專屬節點。
Managed C++ 開發 Windows 服務具備完整 .NET 功能,且不受其他 .NET 語言限制,僅受想像力限制。注意 C++/VB/C# 專案模板細微差異即可順利開發。