.NET 8 में Windows के लिए कोई सेवा बनाएँ

पेज अद्यतन :
पेज निर्माण की तारीख :

परिचालन का वातावरण

विजुअल स्टूडियो
  • विजुअल स्टूडियो 2022
।जाल
  • .नेट 8
विंडोज़
  • विंडोज 11

आवश्यकताएँ

विजुअल स्टूडियो
  • विजुअल स्टूडियो 2022
।जाल
  • .नेट 8
विंडोज़
  • विंडोज 10
  • विंडोज 11
विंडोज सर्वर
  • Windows 2012 या बाद का संस्करण

पूर्व शर्त

  • Visual Studio पहले से स्थापित है

पहले

जब मैं Visual Studio .NET में एक Windows सेवा बनाने का प्रयास करें, केवल .NET Framework टेम्पलेट हैं। इसे .NET (कोर) में भी बनाया जा सकता है, और टेम्पलेट का नाम "वर्कर सर्विस" है।

इस लेख में, मैं समझाऊंगा कि विंडोज सेवा बनाने, पंजीकरण करने और चलाने के लिए इसका उपयोग कैसे करें। प्रसंस्करण सामग्री न्यूनतम है, इसलिए यदि आप पुष्टि कर सकते हैं कि यह विंडोज सेवा के रूप में चल रहा है, तो कृपया फ़ंक्शन बनाएं।

एक प्रोजेक्ट बनाएं

Visual Studio प्रारंभ करें। नया प्रोजेक्ट बनाएं चुनें.

ऊपर खोज फ़ील्ड में दर्ज करें サービス , और फिर सूची से कार्यकर्ता सेवा का चयन करें। "विंडोज सर्विसेज" .NET फ्रेमवर्क संस्करण है, जिसमें .NET संस्करण नहीं है।

परियोजना का नाम और स्थान मनमाना हो सकता है। यह उस सेवा को प्रभावित नहीं करता है जिसके लिए आप पंजीकरण कर रहे हैं।

「. NET 8.0 चयनित है, और इसे बनाने के लिए डिफ़ॉल्ट छोड़ दें।

परियोजना बनाई गई है।

लाइब्रेरीज़ जोड़ना

प्रारंभिक स्थिति में, इसमें केवल एक "सेवा" फ़ंक्शन है और कोई विंडोज-विशिष्ट फ़ंक्शन नहीं है। एक लाइब्रेरी जोड़ें जिसका उपयोग NuGet से Windows सेवा द्वारा किया जा सकता है।

निर्भरता पर राइट-क्लिक करें और NuGet Packages प्रबंधित करें चुनें.

ब्राउज़ टैब का चयन करें और खोज फ़ील्ड में प्रवेश करें Microsoft.Extensions.Hosting.WindowsServices । यह सूची में दिखाई देगा, इसलिए इसे स्थापित करें।

लागू करें पर क्लिक करें.

इसे पैकेज के रूप में जोड़ा गया था।

कार्यक्रमों का संपादन

इस बार, मैं एक ऐसी सेवा बनाऊंगा जो समय-समय पर पाठ फ़ाइल में श्री/सुश्री के रूप में पाठ जोड़ती है।

Program.cs

Windows सेवा की कार्यक्षमता निम्नानुसार जोड़ें:

var builder = Host.CreateApplicationBuilder(args);
// ↓ここから追加
builder.Services.AddWindowsService();
// ↑ここまで追加
builder.Services.AddHostedService<Worker>();

var host = builder.Build();
host.Run();

Worker.cs

आप क्लास का नाम मनमाने ढंग से बदल सकते हैं, लेकिन इस समय के लिए हम डिफ़ॉल्ट छोड़ देंगे।

डिफ़ॉल्ट रूप से, केवल ऐसे तरीके हैं जो सेवा निष्पादित होने पर संसाधित होते हैं ExecuteAsync , लेकिन आइए इसे निम्नानुसार बदलें:

public class Worker : BackgroundService
{
  private readonly ILogger<Worker> _logger;

  /// <summary>ログの出力先フォルダパス。</summary>
  private const string OutputLogFolderPath = @"C:\Temporary\";

  /// <summary>ログの出力先ファイルパス。</summary>
  private const string OutputLogFilePath = @$"{OutputLogFolderPath}Test.log";


  public Worker(ILogger<Worker> logger)
  {
    _logger = logger;
  }

  /// <summary>
  /// サービスが開始されたときに呼ばれます。
  /// </summary>
  /// <param name="stoppingToken"></param>
  /// <returns></returns>
  public override async Task StartAsync(CancellationToken stoppingToken)
  {
    if (Directory.Exists(OutputLogFolderPath) == false)
    {
      Directory.CreateDirectory(OutputLogFolderPath);
    }
    File.AppendAllText(OutputLogFilePath, $"StartAsync サービスを開始しました。\r\n");

    await base.StartAsync(stoppingToken);
  }

  /// <summary>
  /// サービスが終了したときに呼ばれます。
  /// </summary>
  /// <param name="stoppingToken"></param>
  /// <returns></returns>
  public override async Task StopAsync(CancellationToken stoppingToken)
  {
    File.AppendAllText(OutputLogFilePath, $"StopAsync サービスを終了しました。\r\n");
    File.AppendAllText(OutputLogFilePath, $"------------------------------\r\n");

    await base.StopAsync(stoppingToken);
  }

  /// <summary>
  /// サービスが実行されたときに呼ばれます。
  /// </summary>
  /// <param name="stoppingToken">サービスの非同期キャンセルトークン。</param>
  /// <returns></returns>
  protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  {
    while (!stoppingToken.IsCancellationRequested)
    {
      File.AppendAllText(OutputLogFilePath, $"{DateTime.Now}\r\n");

      if (_logger.IsEnabled(LogLevel.Information))
      {
        _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
      }
      await Task.Delay(1000 * 60, stoppingToken);
    }
  }
}

हमने एक नई विधि और StopAsync एक नई StartAsync विधि जोड़ी है। जैसा कि नाम से ही स्पष्ट है, इन विधियों को तब कहा जाता है जब सेवा शुरू होती है और जब इसे रोक दिया जाता है। प्रक्रिया की सामग्री केवल फ़ोल्डर बना रही है और पाठ लिख रही है, इसलिए मैं स्पष्टीकरण को छोड़ दूंगा।

ExecuteAsync विधि stoppingToken के साथ लूप करना जारी रखती है जब तक while कि इसे रद्द करने के लिए ध्वजांकित नहीं किया जाता है। सेवा के चलने के दौरान आप जो संसाधित करना चाहते हैं उसे while जोड़ें. हालाँकि, यदि आप केवल उस प्रक्रिया को लिखते हैं जिसे आप स्थानांतरित करना चाहते हैं, तो सेवा पूरी क्षमता से चल रही होगी, इसलिए Task.Delay विधि के साथ एक निश्चित समय की प्रतीक्षा करते हुए इसे स्थानांतरित करना बुनियादी है। डिफ़ॉल्ट रूप से, यह 1 सेकंड (1000ms) पर सेट होता है, इसलिए कृपया इसे किसी भी समय फिर से लिखें।

डीबग

आप Visual Studio से डीबग कर सकते हैं। निश्चिंत रहें कि आप वास्तव में सेवा के साथ पंजीकृत नहीं होंगे।

जब आप इसे चलाते हैं, तो कंसोल दिखाई देगा।

यदि प्रक्रिया सही है, तो आप देख सकते हैं कि फ़ाइल बनाई गई है।

यदि आप डीबगिंग को रोकना चाहते हैं, तो कंसोल बंद करें।

यदि आप लॉग की जांच करते हैं, तो आप देख सकते हैं कि सेवा प्रारंभ प्रक्रिया बीत चुकी है, लेकिन समाप्ति प्रक्रिया नहीं है। समाप्ति देखने के लिए, आपको इसे सत्यापित करने के लिए वास्तव में विंडोज सेवा के साथ पंजीकरण करना होगा।

समस्या

विंडोज सेवा के साथ पंजीकरण करने में सक्षम होने के लिए, आपको प्रोग्राम प्रकाशित करना होगा। प्रोजेक्ट पर राइट-क्लिक करें और प्रकाशित करें चुनें.

फ़ोल्डर चुनें.

फ़ोल्डर स्थान डिफ़ॉल्ट रूप से अच्छा है।

प्रकाशन सेटिंग्स बनाई जाएंगी, इसलिए "सभी सेटिंग्स दिखाएं" चुनें।

इसे निम्नानुसार सेट करें:

पैरामीटर नाम मान टिप्पणियाँ
संरूपण रिलीज (डिफ़ॉल्ट)
लक्ष्य ढांचा Net8.0 (डिफ़ॉल्ट)
परिनियोजन मोड फ्रेमवर्क निर्भरता सेवा पंजीकरण वातावरण के लिए अलग से। यदि आप NEt 8 रनटाइम स्थापित कर रहे हैं, तो यह सेटिंग ठीक है।
लक्ष्य रनटाइम जीत-x64 यदि OS एक 32-बिट वातावरण है, तो win-x86 का चयन करें
लक्ष्य स्थान चूक
एकल फ़ाइल बनाना पर
ReadyToRun संकलन स्‍वेच्‍छाचारी

सेटिंग के बाद, "सबमिट" बटन पर क्लिक करें।

यदि निचले बाएँ कोने में "प्रकाशन सफल रहा" प्रदर्शित होता है, तो यह पूर्ण है।

आउटपुट फ़ाइल को "लक्ष्य स्थान" पर क्लिक करके खोला जा सकता है।

सेवाओं में कार्यक्रम प्लेसमेंट और नामांकन

उस वातावरण में लॉग इन करें जहाँ आप Windows सेवा को व्यवस्थापक विशेषाधिकारों के साथ पंजीकृत करना चाहते हैं.

प्रकाशित फ़ाइल की उस वातावरण में प्रतिलिपि बनाएँ जहाँ आप इसे Windows सेवा के रूप में पंजीकृत करना चाहते हैं. आप इसे किसी भी फ़ोल्डर में रख सकते हैं, लेकिन ध्यान रखें कि विंडोज सेवा हमेशा उस फ़ोल्डर में प्रोग्राम को संदर्भित करेगी।

साथ ही, यदि प्रकाशित फ़ाइल में एक्सटेंशन .pdb वाली फ़ाइल है, तो इसे ऐसे वातावरण में कॉपी न करें जहां इसे किसी अनिर्दिष्ट व्यक्ति द्वारा देखा जा सकता है क्योंकि इसमें विकास जानकारी है।

एक बार फ़ाइल हो जाने के बाद, इसे विंडोज सेवा के रूप में पंजीकृत करें। रजिस्टर करने के लिए कमांड का उपयोग करें। स्टार्ट मेन्यू पर राइट-क्लिक करें और "टर्मिनल (एडमिन)" चुनें। श्री/सुश्री विंडोज 11 वातावरण में चल रहा है, लेकिन अन्य वातावरणों में, व्यवस्थापक विशेषाधिकारों के साथ कमांड प्रॉम्प्ट खोलना ठीक है।

टर्मिनल के मामले में, PowerShell पहले खुला हो सकता है, लेकिन PowerShell इसे सही ढंग से सेट करने में सक्षम नहीं हो सकता है, इसलिए "कमांड प्रॉम्प्ट" खोलें।

आप इसे निम्न कमांड के साथ विंडोज सेवा के साथ पंजीकृत कर सकते हैं:

प्रारूप

sc create "<サービス名>" start=auto binpath="<プログラム(.exe)のパス>"

उदाहरण इनपुट

sc create "WindowsServiceDotNet8" start=auto binpath="C:\Service\WindowsServiceDotNet8\WindowsServiceDotNet8.exe"

<サービス名> वह नाम है जो Windows सेवाओं की सूची में प्रकट होता है. आप एक अलग प्रदर्शन नाम सेट कर सकते हैं, लेकिन यदि आप कोई प्रदर्शन नाम निर्दिष्ट नहीं करते हैं, तो यह नाम प्रदर्शित किया जाएगा. यह रजिस्ट्री को भी प्रभावित करता है, इसलिए अल्फ़ान्यूमेरिक सेवा नामों को प्राथमिकता दी जाती है।

start=auto Windows के प्रारंभ होने पर सेवा को स्वचालित रूप से प्रारंभ करने के लिए एक सेटिंग है. यदि आप इसे मैन्युअल रूप से प्रारंभ करना चाहते हैं, तो इस वर्णन को हटाएँ.

binpath प्रोग्राम फ़ाइलों का पूरा पथ है।

यदि आप कमांड निष्पादित करते हैं और [SC] CreateService SUCCESS प्रदर्शन करते हैं, तो यह सफल होता है।

आपके द्वारा पंजीकृत सेवाएं सूची में दिखाई देनी चाहिए।

सेवा प्रारंभ करें और इसके संचालन की जाँच करें

यदि आप सेवा चलाना चाहते हैं, तो आप इसे सर्विस स्क्रीन से या निम्न कमांड से शुरू कर सकते हैं।

sc start <サービス名>

स्टॉप कमांड इस प्रकार है।

sc stop <サービス名>

यदि आप सेवा रोकते हैं, तो आप सत्यापित कर सकते हैं कि शट डाउन प्रक्रिया चल रही है।

सेवा में विवरण जोड़ें

जोड़ी गई सेवा का विवरण फ़ील्ड रिक्त है, लेकिन आप इसे निम्न कमांड के साथ जोड़ सकते हैं।

sc description <サービス名> "<説明文>"

किसी सेवा को हटाना

यदि आप सेवा को हटाना चाहते हैं, तो आप निम्न कमांड के साथ ऐसा कर सकते हैं। कमांड प्रॉम्प्ट पर आपके पास व्यवस्थापक विशेषाधिकार होने चाहिए.

sc delete <サービス名>