[TIL] .NET Framework 윈도우 서비스 배포 고려하기

iamwoosung·2025년 4월 15일

TIL

목록 보기
1/5

📌 Summary

개발 산출물을 배포할 때에는 고려해야 할 항목들이 정말 많은 거 같다.
사용자가 느끼는 불편함이 곧 서비스에 대한 불만족이기 때문에 부정적인 요소들을 최대한 배제해야 한다.
윈도우 서비스 배포 시에는 아래 항목들을 주의해야 한다.

  • 윈도우 서비스 배포 시 바이너리의 속성, 값 설정 방법
  • 설치 관리자 추가와 서비스 install 코드 작성 방법
  • 서비스 설치 시 사용자 권한 설정 방법
  • 디버그 모드 지원 방법

P.S. 해당 포스트는 Visual Studio 2022로 작성되었습니다.






📌 Issue & Solution

✨ 바이너리 속성 설정 방법

Properties의 AssemblyInfo.cs에는 속성 값이 저장되어 있다.

[assembly: AssemblyTitle("타이틀입니다")]
[assembly: AssemblyDescription("설명입니다")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("회사명입니다")]
[assembly: AssemblyProduct("제품명입니다")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

프로젝트가 bin에 빌드 되면서 .exe 파일이 생성되는데 해당 파일에 대한 정보이다.


이걸 굳이 왜 넣어야 되냐면 개발사 정보 및 저작권에 대해 명시되어 있기도 하고,
현장에 설치 및 운영하던 중 이슈가 발생했을 때, 파일의 버전으로 추적이 용이해지기 때문이다.
(현장 방문이 어려운 상황일 때, 프로그램 버전만 알 수 있다면 사무실에서 클론 시험이 가능하다.)




✨ 설치 관리자 추가

윈도우 서비스 프로젝트는 아래와 같이 생성된다.

Service1.cs 디자인 뷰에서 우클릭 시 나타나는 설치 관리자를 추가를 클릭해 보자
(Visual Studio 2015~2019에서는 Service1.cs 속성에 설치 관리자가 있었던 거 같다.)

그럼 아래와 같은 파일들이 생성된다.

ProjectInstaller.Designer.cs 파일에 서비스 설치와 관련한 코드가 작성되어 있다.

this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
// 
// serviceProcessInstaller1
// 
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
// 
// serviceInstaller1
// 
// 서비스 설치 시 서비스 명칭이다. 배포 시 수정 필요
this.serviceInstaller1.ServiceName = "Service1";
// 
// ProjectInstaller
// 
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1,
this.serviceInstaller1});




✨ 서비스 설치 코드 작성

윈도우 OS에 서비스를 등록하기 위해 흔히들 SVC 라이브러리나 별도 툴을 이용한다.
하지만 C#에서는 코드 상에서 현재 실행 중인 바이너리를 서비스에 등록할 수 있다.

private static string binaryPath = Assembly.GetExecutingAssembly().Location;

static void fnServiceInstall() {
	ManagedInstallerClass.InstallHelper(new string[] {
		binaryPath
	});
}
static void fnServiceUninstall() {
	ManagedInstallerClass.InstallHelper(new string[] {
		'/u', binaryPath
	});
}

Arguments로 커맨드를 받아서 서비스 install, uninstall, start, stop을 처리한다.




✨ 서비스 설치 시 권한 부여

실제 install 명령을 Arguments로 실행해 보면 아래와 같은 팝업이 표출된다.

서비스 로그인 계정을 매번 입력하기 불편하니 코드 상에서 계정 정보를 넣어줄 수 있다.
위에서 생성했던 ProjectInstaller.Designer.cs 파일에 아래 계정 코드를 추가하자.

// 추가
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
// 기존 코드
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;




✨ 디버그 모드 지원

사무실에서 명세서만 보고 개발한 산출물은 현장 구축, 운영 시 문제점이 발생하기 마련이다.
그렇다고 현장에 IDE를 설치할 수 없는 노릇이니, 프로그램 자체적인 디버그 방법을 마련해 현장에서 이슈에 대한 원인 분석 및 해결이 가능하도록 해야 한다.


가장 좋은 것은 모든 로직에 로그 생성 기능을 포함하는 것이다.
로그 레벨을 설정하고, Info, Error, Warning에 대한 로그를 찍으면 원인 추적이 가능해진다.


또 다른 방법은 CMD로 실행 시 콘솔 출력을 하는 것이다.
CMD로 프로그램을 실행할 때 Arguments로 디버그 모드임을 알려주고, 프로그램은 그에 따라 콘솔 출력을 수행한다. 프롬프트에는 콘솔에 출력한 내용들이 표출될 것이므로, 로그 파일을 뒤져보지 않더라도 좀 더 간편한 방법으로 디버깅이 가능하다.






📌 References

🔗 설치 관리자
🔗 설치 관리자 추가
🔗 서비스 계정

0개의 댓글