윈도우 서비스란?
시스템 부팅~종료시점까지 그 수명을 같이 하는 프로세스
프로젝트 구조

누겟 패키지 설치
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
프로그램 작성
Program.cs
using Microsoft.Extensions.Logging.Configuration;
using Microsoft.Extensions.Logging.EventLog;
using App.JokeService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
var services = builder.Services;
// 중요. 없으면 윈도우 서비스로 등록할 수 없음
services.AddWindowsService();
// 로그 설정하는건가봄
LoggerProviderOptions.RegisterProviderOptions<EventLogSettings, EventLogLoggerProvider>(services);
//의존성 주입
services.AddSingleton<JokeService>();
//백그라운드 스케줄러 등록
services.AddHostedService<WindowsBackgroundService>();
var host = builder.Build();
host.Run();
WindowBackgroundService.cs
public sealed class WindowsBackgroundService : BackgroundService
{
private readonly JokeService _jokeService;
private readonly ILogger<WindowsBackgroundService> _logger;
public WindowsBackgroundService(JokeService jokeService, ILogger<WindowsBackgroundService> logger)
{
_jokeService = jokeService;
_logger = logger;
}
//1분마다 농담 출력
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
while (!stoppingToken.IsCancellationRequested)
{
string joke = _jokeService.GetJoke();
_logger.LogWarning("{joke}", joke);
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
}
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
Environment.Exit(1);
}
}
}
JokeService.cs
public sealed class JokeService
{
public string GetJoke()
{
Joke joke = _jokes.ElementAt(Random.Shared.Next(_jokes.Count));
return $"{joke.Setup}{Environment.NewLine}{joke.Punchline}";
}
private readonly HashSet<Joke> _jokes = new()
{
new Joke("What's the best thing about a Boolean?", "Even if you're wrong, you're only off by a bit."),
new Joke("What's the object-oriented way to become wealthy?", "Inheritance"),
new Joke("Why did the programmer quit their job?", "Because they didn't get arrays."),
new Joke("Why do programmers always mix up Halloween and Christmas?", "Because Oct 31 == Dec 25"),
new Joke("How many programmers does it take to change a lightbulb?", "None that's a hardware problem"),
new Joke("If you put a million monkeys at a million keyboards, one of them will eventually write a Java program", "the rest of them will write Perl"),
new Joke("['hip', 'hip']", "(hip hip array)"),
new Joke("To understand what recursion is...", "You must first understand what recursion is"),
new Joke("There are 10 types of people in this world...", "Those who understand binary and those who don't"),
new Joke("Which song would an exception sing?", "Can't catch me - Avicii"),
new Joke("Why do Java programmers wear glasses?", "Because they don't C#"),
new Joke("How do you check if a webpage is HTML5?", "Try it out on Internet Explorer"),
new Joke("A user interface is like a joke.", "If you have to explain it then it is not that good."),
new Joke("I was gonna tell you a joke about UDP...", "...but you might not get it."),
new Joke("The punchline often arrives before the set-up.", "Do you know the problem with UDP jokes?"),
new Joke("Why do C# and Java developers keep breaking their keyboards?", "Because they use a strongly typed language."),
new Joke("Knock-knock.", "A race condition. Who is there?"),
new Joke("What's the best part about TCP jokes?", "I get to keep telling them until you get them."),
new Joke("A programmer puts two glasses on their bedside table before going to sleep.", "A full one, in case they gets thirsty, and an empty one, in case they don’t."),
new Joke("There are 10 kinds of people in this world.", "Those who understand binary, those who don't, and those who weren't expecting a base 3 joke."),
new Joke("What did the router say to the doctor?", "It hurts when IP."),
new Joke("An IPv6 packet is walking out of the house.", "He goes nowhere."),
new Joke("3 SQL statements walk into a NoSQL bar. Soon, they walk out", "They couldn't find a table.")
};
}
readonly record struct Joke(string Setup, string Punchline);
참고 https://learn.microsoft.com/ko-kr/dotnet/core/extensions/windows-service
BackgroundService를 사용하여 Windows 서비스 만들기 - .NET
.NET에서 BackgroundService를 사용하여 Windows Service를 만드는 방법을 알아봅니다.
learn.microsoft.com
배포하기
.csproj 파일 수정
<PropertyGroup>
...
<OutputType>exe</OutputType>
<PublishSingleFile Condition="'$(Configuration)' == 'Release'">true</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
배포 프로필 만들고 게시하기

서비스 등록하기
파워셀 관리자 권한으로 실행 후 다음 명령어 입력
sc.exe create 서비스이름 binPath= "서비스 exe 파일 실행 경로" start= auto
작업관리자 > 서비스 > 위에서 등록한 서비스이름 우클릭 > 실행
서비스 삭제하기
cmd 관리자 권한으로 실행
sc delete 서비스이름'C#' 카테고리의 다른 글
| Serilog 로그 설정 (0) | 2024.05.19 |
|---|---|
| [WorkerService] Quartz 사용하기 (0) | 2024.04.18 |
| C# Supersocket (0) | 2023.08.14 |
| C# 기본 이론 정리 (0) | 2023.01.11 |