다음을 통해 공유


자습서: Windows 서비스 앱 만들기

이 문서에서는 Visual Studio에서 .NET Framework Windows 서비스 앱을 만드는 방법을 보여 줍니다. 서비스는 단순히 이벤트 로그에 메시지를 씁니다.

비고

이 문서는 .NET의 호스트된 서비스에는 적용되지 않습니다. Windows 서비스 사용 Microsoft.Extensions.Hosting.BackgroundService 및 작업자 서비스 템플릿의 최신 콘텐츠는 다음을 참조하세요.

서비스 만들기

시작하려면 프로젝트를 만들고 서비스가 올바르게 작동하는 데 필요한 값을 설정합니다.

  1. Visual Studio 파일 메뉴에서 >프로젝트를 선택하거나 Ctrl+Shift+N을 눌러 새 프로젝트 창을 엽니다.

  2. Windows 서비스(.NET Framework) 프로젝트 템플릿을 찾아 선택합니다.

    비고

    Windows 서비스 템플릿이 표시되지 않으면 Visual Studio 설치 관리자를 사용하여 .NET 데스크톱 개발 워크로드를 설치해야 할 수 있습니다.

  3. 프로젝트 이름MyNewService를 입력한 다음 만들기를 선택합니다.

    디자인 탭이 나타납니다 (Service1.cs [디자인] 또는 Service1.vb [디자인]).

    프로젝트 템플릿에는 Service1이라는 이름의 구성 요소 클래스가 있으며, 이는 System.ServiceProcess.ServiceBase 에서 상속됩니다. 여기에는 서비스를 시작하는 코드와 같은 대부분의 기본 서비스 코드가 포함됩니다.

서비스 이름 바꾸기

서비스 이름을 Service1 에서 MyNewService로 바꿉니다.

  1. 솔루션 탐색기에서 Service1.cs 또는 Service1.vb 선택하고 바로 가기 메뉴에서 이름 바꾸기를 선택합니다. 파일 이름을 MyNewService.cs 또는 MyNewService.vb 이름을 바꾼 다음 Enter 키를 누릅니 .

    코드 요소 Service1에 대한 모든 참조의 이름을 바꿀지 여부를 묻는 팝업 창이 나타납니다.

  2. 팝업 창에서 예를 선택합니다.

    프롬프트 이름 바꾸기

  3. 파일 메뉴에서 모두 저장을 선택합니다.

서비스에 기능 추가

이 섹션에서는 Windows 서비스에 사용자 지정 이벤트 로그를 추가합니다. EventLog 구성 요소는 Windows 서비스에 추가할 수 있는 구성 요소 형식의 예입니다.

사용자 지정 이벤트 로그 기능 추가

  1. 도구 상자 창에서 구성 요소를 확장한 다음 EventLog 구성 요소를 Service1.cs [디자인] 또는 Service1.vb [디자인] 디자이너로 드래그합니다.

    팁 (조언)

    도구 상자 창이 표시되지 않으면도구 상자> 선택합니다.

  2. 솔루션 탐색기의MyNewService.cs 또는 MyNewService.vb 바로 가기 메뉴에서 코드 보기를 선택합니다.

  3. 사용자 지정 이벤트 로그를 정의합니다.

    C#의 경우 다음 코드 조각에 표시된 대로 기존 MyNewService() 생성자를 편집합니다. Visual Basic의 New() 경우 다음 코드 조각과 같이 생성자를 추가합니다.

    public MyNewService()
    {
        InitializeComponent();
        eventLog1 = new EventLog();
        if (!EventLog.SourceExists("MySource"))
        {
            EventLog.CreateEventSource("MySource", "MyNewLog");
        }
        eventLog1.Source = "MySource";
        eventLog1.Log = "MyNewLog";
    }
    
    ' To access the constructor in Visual Basic, select New from the
    ' method name drop-down list. 
    Public Sub New()
        MyBase.New()
        InitializeComponent()
        Me.EventLog1 = New System.Diagnostics.EventLog
        If Not System.Diagnostics.EventLog.SourceExists("MySource") Then
            System.Diagnostics.EventLog.CreateEventSource("MySource",
            "MyNewLog")
        End If
        EventLog1.Source = "MySource"
        EventLog1.Log = "MyNewLog"
    End Sub
    
  4. 아직 없는 경우 System.Diagnosticsusing에 지시문을 추가하거나, Imports에 문을 추가합니다.

    using System.Diagnostics;
    
    Imports System.Diagnostics
    
  5. 파일 메뉴에서 모두 저장을 선택합니다.

서비스가 시작될 때 발생하는 사항 정의

MyNewService.cs 또는 MyNewService.vb 대한 코드 편집기에서 메서드를 찾습니다OnStart. 프로젝트를 만들 때 Visual Studio에서 빈 메서드 정의를 자동으로 만들었습니다. 서비스가 시작될 때 이벤트 로그에 항목을 쓰는 코드를 추가합니다.

protected override void OnStart(string[] args)
{
    eventLog1.WriteEntry("In OnStart.");
}
' To access the OnStart in Visual Basic, select OnStart from the
' method name drop-down list. 
Protected Overrides Sub OnStart(ByVal args() As String)
    EventLog1.WriteEntry("In OnStart")
End Sub

폴링

서비스 애플리케이션은 장기 실행되도록 설계되었으므로 일반적으로 메서드에서 OnStart 설정한 시스템을 폴링하거나 모니터링합니다. OnStart 시스템이 차단되지 않도록 서비스의 작업이 시작된 후 메서드가 운영 체제로 돌아가야 합니다.

간단한 폴링 메커니즘을 설정하려면 System.Timers.Timer 구성 요소를 사용합니다. 타이머는 정기적으로 이벤트를 발생 Elapsed 시키는데, 이때 서비스에서 모니터링을 수행할 수 있습니다. 다음과 같이 구성 요소를 사용합니다 Timer .

  • 메서드에서 구성 요소 TimerMyNewService.OnStart 속성을 설정합니다.
  • 메서드를 호출하여 타이머를 시작합니다 Start .
폴링 메커니즘 설정
  1. using 지시문을 MyNewService.cs에 추가하거나, Imports 문을 MyNewService.vb에 추가하여 네임스페이스를 설정합니다.

    using System.Timers;
    
    Imports System.Timers
    
  2. 이벤트에 다음 코드를 MyNewService.OnStart 추가하여 폴링 메커니즘을 설정합니다.

    // Set up a timer that triggers every minute.
    Timer timer = new Timer
    {
        Interval = 60000 // 60 seconds
    };
    timer.Elapsed += new ElapsedEventHandler(this.OnTimer);
    timer.Start();
    
    ' Set up a timer that triggers every minute.
    Dim timer As Timer = New Timer()
    timer.Interval = 60000 ' 60 seconds
    AddHandler timer.Elapsed, AddressOf Me.OnTimer
    timer.Start()
    
  3. 클래스에서 MyNewService 멤버 변수를 추가합니다. 이벤트 로그에 쓸 다음 이벤트의 식별자를 포함합니다.

    private int eventId = 1;
    
    Private eventId As Integer = 1
    
  4. 클래스 MyNewService에서 Timer.Elapsed 이벤트를 처리하기 위해 메서드 OnTimer을(를) 추가 합니다.

    public void OnTimer(object sender, ElapsedEventArgs args)
    {
        // TODO: Insert monitoring activities here.
        eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId++);
    }
    
    Private Sub OnTimer(sender As Object, e As Timers.ElapsedEventArgs)
       ' TODO: Insert monitoring activities here.
       eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId)
       eventId = eventId + 1
    End Sub
    

주 스레드에서 모든 작업을 실행하는 대신 백그라운드 작업자 스레드를 사용하여 작업을 실행할 수 있습니다. 자세한 내용은 System.ComponentModel.BackgroundWorker를 참조하세요.

서비스가 중지될 때 발생하는 동작 정의

서비스가 중지될 때 이벤트 로그에 OnStop 항목을 추가하는 코드 줄을 메서드에 삽입합니다.

protected override void OnStop()
{
    eventLog1.WriteEntry("In OnStop.");
}
Protected Overrides Sub OnStop()
    EventLog1.WriteEntry("In OnStop.")
End Sub

서비스에 대한 다른 작업 정의

OnPause, OnContinue, OnShutdown 메서드를 재정의하여 구성 요소에 대한 추가 처리를 정의할 수 있습니다.

다음 코드는 MyNewService 클래스에서 OnContinue 메서드를 재정의하는 방법을 보여 줍니다.

protected override void OnContinue()
{
    eventLog1.WriteEntry("In OnContinue.");
}
Protected Overrides Sub OnContinue()
    EventLog1.WriteEntry("In OnContinue.")
End Sub

서비스 상태 설정

서비스는 서비스가 제대로 작동하는지 여부를 사용자가 알 수 있도록 서비스 제어 관리자 에 상태를 보고합니다. 기본적으로 ServiceBase을(를) 상속하는 서비스는 SERVICE_STOPPED, SERVICE_PAUSED, 및 SERVICE_RUNNING를 포함하는 제한된 상태 설정 집합을 보고합니다. 서비스를 시작하는 데 시간이 걸리는 경우, SERVICE_START_PENDING 상태를 보고하는 것이 유용합니다.

SERVICE_START_PENDINGSERVICE_STOP_PENDING 상태 설정은 Windows SetServiceStatus 함수를 호출하는 코드를 추가하여 구현할 수 있습니다.

  1. using 지시문을 MyNewService.cs에 추가하거나, Imports 문을 MyNewService.vb에 추가하여 네임스페이스를 설정합니다.

    using System.Runtime.InteropServices;
    
    Imports System.Runtime.InteropServices
    
  2. 다음 열거형 및 구조체를 MyNewService.cs 또는 MyNewService.vb에 추가하여, 플랫폼 호출에서 사용할 상태 구조체를 설정하고 값을 선언하세요.

    public enum ServiceState
    {
        SERVICE_STOPPED = 0x00000001,
        SERVICE_START_PENDING = 0x00000002,
        SERVICE_STOP_PENDING = 0x00000003,
        SERVICE_RUNNING = 0x00000004,
        SERVICE_CONTINUE_PENDING = 0x00000005,
        SERVICE_PAUSE_PENDING = 0x00000006,
        SERVICE_PAUSED = 0x00000007,
    }
    
    [StructLayout(LayoutKind.Sequential)]
    public struct ServiceStatus
    {
        public int dwServiceType;
        public ServiceState dwCurrentState;
        public int dwControlsAccepted;
        public int dwWin32ExitCode;
        public int dwServiceSpecificExitCode;
        public int dwCheckPoint;
        public int dwWaitHint;
    };
    
    Public Enum ServiceState
        SERVICE_STOPPED = 1
        SERVICE_START_PENDING = 2
        SERVICE_STOP_PENDING = 3
        SERVICE_RUNNING = 4
        SERVICE_CONTINUE_PENDING = 5
        SERVICE_PAUSE_PENDING = 6
        SERVICE_PAUSED = 7
    End Enum
    
    <StructLayout(LayoutKind.Sequential)>
    Public Structure ServiceStatus
        Public dwServiceType As Long
        Public dwCurrentState As ServiceState
        Public dwControlsAccepted As Long
        Public dwWin32ExitCode As Long
        Public dwServiceSpecificExitCode As Long
        Public dwCheckPoint As Long
        Public dwWaitHint As Long
    End Structure
    

    비고

    Service Control Manager는 dwWaitHint체의 멤버 및 dwCheckpoint 멤버를 사용하여 Windows 서비스가 시작되거나 종료되기를 기다리는 시간을 결정합니다. 사용자 OnStartOnStop 메서드가 장시간 실행되는 경우, 서비스는 증가된 dwCheckPoint 값을 사용하여 SetServiceStatus를 다시 호출하여 더 많은 시간을 요청할 수 있습니다.

  3. MyNewService 클래스에서 플랫폼 호출을 사용하여 SetServiceStatus 함수를 선언합니다.

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool SetServiceStatus(System.IntPtr handle, ref ServiceStatus serviceStatus);
    
    Declare Auto Function SetServiceStatus Lib "advapi32.dll" (ByVal handle As IntPtr, ByRef serviceStatus As ServiceStatus) As Boolean
    
  4. SERVICE_START_PENDING 상태를 구현하려면 OnStart 메서드의 시작 부분에 다음 코드를 추가합니다.

    // Update the service state to Start Pending.
    ServiceStatus serviceStatus = new ServiceStatus
    {
        dwCurrentState = ServiceState.SERVICE_START_PENDING,
        dwWaitHint = 100000
    };
    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
    ' Update the service state to Start Pending.
    Dim serviceStatus As ServiceStatus = New ServiceStatus()
    serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING
    serviceStatus.dwWaitHint = 100000
    SetServiceStatus(Me.ServiceHandle, serviceStatus)
    
  5. 메서드의 OnStart 끝에 코드를 추가하여 상태를 다음으로 SERVICE_RUNNING설정합니다.

    // Update the service state to Running.
    serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
    ' Update the service state to Running.
    serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING
    SetServiceStatus(Me.ServiceHandle, serviceStatus)
    
  6. (선택 사항) 장기 실행 메서드인 경우 OnStop 메서드에서 이 절차를 반복합니다 OnStop . SERVICE_STOP_PENDING 상태를 구현하고 메서드가 SERVICE_STOPPED 종료되기 전에 OnStop 상태를 반환합니다.

    다음은 그 예입니다.

    // Update the service state to Stop Pending.
    ServiceStatus serviceStatus = new ServiceStatus
    {
        dwCurrentState = ServiceState.SERVICE_STOP_PENDING,
        dwWaitHint = 100000
    };
    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
    // Update the service state to Stopped.
    serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED;
    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
    ' Update the service state to Stop Pending.
    Dim serviceStatus As ServiceStatus = New ServiceStatus()
    serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING
    serviceStatus.dwWaitHint = 100000
    SetServiceStatus(Me.ServiceHandle, serviceStatus)
    
    ' Update the service state to Stopped.
    serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED
    SetServiceStatus(Me.ServiceHandle, serviceStatus)
    

서비스에 설치 관리자 추가

Windows 서비스를 실행하기 전에 서비스 제어 관리자에 등록하는 Windows 서비스를 설치해야 합니다. 등록 세부 정보를 처리하는 설치 관리자를 프로젝트에 추가합니다.

  1. 솔루션 탐색기의MyNewService.cs 또는 MyNewService.vb 바로 가기 메뉴에서 뷰 디자이너를 선택합니다.

  2. 디자인 보기에서 배경 영역을 선택한 다음 바로 가기 메뉴에서 설치 관리자 추가를 선택합니다.

    기본적으로 Visual Studio는 두 개의 설치 관리자를 포함하는 이름이 지정된 ProjectInstaller구성 요소 클래스를 프로젝트에 추가합니다. 이러한 설치 관리자는 서비스와 서비스의 연결된 프로세스를 위한 것입니다.

  3. ProjectInstaller디자인 보기에서 C# 프로젝트의 serviceInstaller1 또는 Visual Basic 프로젝트의 경우 ServiceInstaller1을 선택한 다음 바로 가기 메뉴에서 속성을 선택합니다.

  4. 속성 창에서 속성을 ServiceName로 설정합니다.

  5. 속성에 Description 텍스트(예: 샘플 서비스)를 추가합니다.

    이 텍스트는 서비스 창의 설명 열에 표시되고 사용자에게 서비스를 설명합니다.

    서비스 창의 서비스 설명입니다.

  6. 속성에 DisplayName 텍스트를 추가합니다. 예를 들어 MyNewService 표시 이름입니다.

    이 텍스트는 서비스 창의 표시 이름 열에 나타납니다. 이 이름은 시스템이 사용하는 ServiceName 속성의 이름과 다를 수 있습니다 (예: 서비스를 시작하기 위해 net start 명령에 사용하는 이름).

  7. StartType 속성을 드롭다운 목록에서 Automatic로 설정합니다.

  8. 완료되면 속성 창이 다음 그림과 같이 표시됩니다.

    Windows 서비스에 대한 설치 관리자 속성

  9. ProjectInstaller디자인 보기에서 C# 프로젝트의 경우 serviceProcessInstaller1 또는 Visual Basic 프로젝트의 경우 ServiceProcessInstaller1을 선택한 다음 바로 가기 메뉴에서 속성을 선택합니다. 드롭다운 목록에서 Account 속성을 LocalSystem로 설정합니다.

    이 설정은 서비스를 설치하고 로컬 시스템 계정을 사용하여 실행합니다.

    중요합니다

    LocalSystem 계정에는 이벤트 로그에 쓰는 기능을 포함하여 광범위한 권한이 있습니다. 악성 소프트웨어의 공격 위험이 높아질 수 있으므로 주의해서 이 계정을 사용하세요. 다른 작업의 경우 로컬 컴퓨터에서 LocalService 권한이 없는 사용자 역할을 하고 원격 서버에 익명 자격 증명을 제공하는 계정을 사용하는 것이 좋습니다. 그러나 이벤트 로그에 쓸 수 있는 권한이 필요하기 때문에 계정을 사용 LocalService 하려고 하면 이 예제가 실패합니다.

설치 관리자에 대한 자세한 내용은 방법: 서비스 애플리케이션에 설치 관리자 추가를 참조하세요.

(선택 사항) 시작 매개 변수 설정

비고

시작 매개 변수를 추가하기 전에 서비스에 정보를 전달하는 가장 좋은 방법인지 여부를 고려합니다. 사용 및 구문 분석이 쉽고 사용자가 쉽게 재정의할 수 있는 반면, 문서 없이 발견하고 사용하기는 더 어려울 수 있습니다. 일반적으로 서비스에 몇 가지 시작 매개 변수 이상이 필요한 경우 레지스트리 또는 구성 파일을 대신 사용해야 합니다.

Windows 서비스는 시작 매개 변수라고도 하는 명령줄 인수를 수락할 수 있습니다. 시작 매개 변수를 처리하는 코드를 추가하면 사용자는 서비스 속성 창에서 고유한 사용자 지정 시작 매개 변수를 사용하여 서비스를 시작할 수 있습니다. 그러나 이러한 시작 매개 변수는 다음에 서비스가 시작될 때 유지되지 않습니다.

시작 매개 변수를 영구적으로 설정하려면 레지스트리에서 설정합니다. 각 Windows 서비스에는 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 하위 키 아래에 레지스트리 항목이 있습니다. 각 서비스의 하위 키에서 매개 변수 하위 키를 사용하여 서비스에서 액세스할 수 있는 정보를 저장합니다. 다른 유형의 프로그램에 대해 수행하는 것과 동일한 방식으로 Windows 서비스에 애플리케이션 구성 파일을 사용할 수 있습니다. 샘플 코드는 다음을 참조하세요 ConfigurationManager.AppSettings.

시작 매개 변수를 추가하려면

  1. MyNewService.cs 또는 MyNewService.vb 입력 매개 변수를 MyNewService 수락하고 처리하도록 생성자를 변경합니다.

    public MyNewService(string[] args)
    {
        InitializeComponent();
    
        string eventSourceName = "MySource";
        string logName = "MyNewLog";
    
        if (args.Length > 0)
        {
            eventSourceName = args[0];
        }
    
        if (args.Length > 1)
        {
            logName = args[1];
        }
    
        eventLog1 = new EventLog();
    
        if (!EventLog.SourceExists(eventSourceName))
        {
            EventLog.CreateEventSource(eventSourceName, logName);
        }
    
        eventLog1.Source = eventSourceName;
        eventLog1.Log = logName;
    }
    
    Public Sub New(ByVal cmdArgs() As String)
        InitializeComponent()
        Dim eventSourceName As String = "MySource"
        Dim logName As String = "MyNewLog"
        If (cmdArgs.Count() > 0) Then
            eventSourceName = cmdArgs(0)
        End If
        If (cmdArgs.Count() > 1) Then
            logName = cmdArgs(1)
        End If
        eventLog1 = New EventLog()
        If (Not EventLog.SourceExists(eventSourceName)) Then
            EventLog.CreateEventSource(eventSourceName, logName)
        End If
        eventLog1.Source = eventSourceName
        eventLog1.Log = logName
    End Sub
    

    이 코드는 사용자가 제공하는 시작 매개 변수에 따라 이벤트 원본 및 로그 이름을 설정합니다. 인수가 제공되지 않으면 기본값을 사용합니다.

  2. Program.cs 선택하거나 MyNewService.Designer.vb 바로 가기 메뉴에서 코드 보기를 선택합니다. 메서드에서 Main 코드를 변경하여 입력 매개 변수를 추가하고 서비스 생성자에 전달합니다.

    static void Main(string[] args)
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[]
        {
            new MyNewService(args)
        };
        ServiceBase.Run(ServicesToRun);
    }
    
    Shared Sub Main(ByVal cmdArgs() As String)
        Dim ServicesToRun() As System.ServiceProcess.ServiceBase = New System.ServiceProcess.ServiceBase() {New MyNewService(cmdArgs)}
        System.ServiceProcess.ServiceBase.Run(ServicesToRun)
    End Sub
    
  3. 명령줄 인수를 지정하려면 ProjectInstaller 클래스에 다음 코드를 추가하거나 ProjectInstaller.vb.

    protected override void OnBeforeInstall(IDictionary savedState)
    {
        string parameter = "MySource1\" \"MyLogFile1";
        Context.Parameters["assemblypath"] = "\"" + Context.Parameters["assemblypath"] + "\" \"" + parameter + "\"";
        base.OnBeforeInstall(savedState);
    }
    
    Protected Overrides Sub OnBeforeInstall(ByVal savedState As IDictionary)
        Dim parameter As String = "MySource1"" ""MyLogFile1"
        Context.Parameters("assemblypath") = """" + Context.Parameters("assemblypath") + """ """ + parameter + """"
        MyBase.OnBeforeInstall(savedState)
    End Sub
    

    일반적으로 이 값에는 Windows 서비스에 대한 실행 파일의 전체 경로가 포함됩니다. 서비스가 올바르게 시작하려면 사용자는 경로 및 각 개별 매개 변수에 대한 따옴표를 제공해야 합니다. 사용자는 ImagePath 레지스트리 항목의 매개 변수를 변경하여 Windows 서비스에 대한 시작 매개 변수를 변경할 수 있습니다. 그러나 더 좋은 방법은 프로그래밍 방식으로 값을 변경하고 관리 또는 구성 유틸리티를 사용하는 등 사용자에게 친숙한 방식으로 기능을 노출하는 것입니다.

서비스 빌드

  1. 솔루션 탐색기의MyNewService 프로젝트에 대한 바로 가기 메뉴에서 속성을 선택합니다.

  2. 애플리케이션 탭의 시작 개체 목록에서 MyNewService.Program(또는 Visual Basic 프로젝트의 하위 주)을 선택합니다.

  3. 프로젝트를 빌드하려면 솔루션 탐색기에서 프로젝트의 바로 가기 메뉴에서 빌드 를 선택하거나 Ctrl+Shift+B를 누릅니다.

서비스 설치

이제 Windows 서비스를 빌드했으므로 설치할 수 있습니다. Windows 서비스를 설치하려면 설치된 컴퓨터에 관리자 자격 증명이 있어야 합니다.

  1. 관리자 자격 증명을 사용하여 Visual Studio용 개발자 명령 프롬프트 를 엽니다.

  2. Visual Studio용 개발자 명령 프롬프트에서 프로젝트의 출력이 포함된 폴더로 이동합니다(기본적으로 프로젝트의 \bin\Debug 하위 디렉터리).

  3. 다음 명령을 입력합니다.

    installutil MyNewService.exe
    

    서비스가 성공적으로 설치되면 명령이 성공을 보고합니다.

    시스템에서 installutil.exe찾을 수 없는 경우 컴퓨터에 있는지 확인합니다. 이 도구는 .NET Framework와 함께 \Microsoft.NET\Framework[64]\framework 버전<%windir%폴더에> 설치됩니다.

    installutil.exe 프로세스가 실패하는 경우 설치 로그를 확인하여 그 이유를 알아보세요. 기본적으로 로그는 서비스 실행 파일과 동일한 폴더에 있습니다. 다음과 같은 경우 설치가 실패할 수 있습니다.

    • RunInstallerAttribute 클래스는 ProjectInstaller 클래스에 없습니다.
    • 속성이 true로 설정되지 않았습니다.
    • 클래스가 ProjectInstallerpublic 정의되지 않았습니다.
    • VS에 대한 개발자 명령 프롬프트를 관리자 권한으로 열지 않았습니다.

자세한 내용은 방법: 서비스 설치 및 제거를 참조하세요.

서비스 시작 및 실행

  1. Windows에서 서비스 데스크톱 앱을 엽니다. Windows+R 을 눌러 실행 상자를 열고 services.msc를 입력한 다음 Enter 키를 누르거나 확인을 선택합니다.

    서비스에서 설정한 표시 이름에 따라 사전순으로 나열된 서비스를 볼 수 있습니다.

    서비스 창의 MyNewService입니다.

  2. 서비스를 시작하려면 서비스의 바로 가기 메뉴에서 시작을 선택합니다.

  3. 서비스를 중지하려면 서비스의 바로 가기 메뉴에서 중지 를 선택합니다.

  4. (선택 사항) 명령줄에서 net start <서비스 이름과 net stop 서비스 이름을><사용하여 서비스를 시작하고 중지합니다.>

서비스의 이벤트 로그 출력 확인

  1. Windows에서 이벤트 뷰어 데스크톱 앱을 엽니다. Windows 검색 창에서 이벤트 뷰어를 입력한 다음 검색 결과에서 이벤트 뷰어를 선택합니다.

    팁 (조언)

    Visual Studio에서는 보기 메뉴에서 서버 탐색기를 열고(또는 Ctrl+Alt+S를 누르고) 로컬 컴퓨터에 대한 이벤트 로그 노드를 확장하여 이벤트 로그에 액세스할 수 있습니다.

  2. 이벤트 뷰어에서 애플리케이션 및 서비스 로그를 확장합니다.

  3. MyNewLog 목록(또는 명령줄 인수를 추가하는 절차를 따른 경우 MyLogFile1)을 찾아서 확장합니다. 서비스에서 수행한 두 작업(시작 및 중지)에 대한 항목이 표시됩니다.

    이벤트 뷰어를 사용하여 이벤트 로그 항목 보기

자원을 정리하세요

Windows 서비스 앱이 더 이상 필요하지 않은 경우 제거할 수 있습니다.

  1. 관리자 자격 증명을 사용하여 Visual Studio용 개발자 명령 프롬프트 를 엽니다.

  2. Visual Studio용 개발자 명령 프롬프트 창에서 프로젝트의 실행 파일이 포함된 폴더로 이동합니다.

  3. 다음 명령을 입력합니다.

    installutil.exe /u MyNewService.exe
    

    서비스가 성공적으로 제거되면 명령은 서비스가 성공적으로 제거되었다고 보고합니다. 자세한 내용은 방법: 서비스 설치 및 제거를 참조하세요.

다음 단계:

이제 서비스를 만들었으므로 다음을 수행할 수 있습니다.

  • 다른 사용자가 Windows 서비스를 설치하는 데 사용할 독립 실행형 설치 프로그램을 만듭니다. WiX 도구 집합을 사용하여 Windows 서비스에 대한 설치 관리자를 만듭니다. 다른 아이디어는 설치 관리자 패키지 만들기를 참조하세요.

  • 설치한 ServiceController 서비스에 명령을 보낼 수 있는 구성 요소를 살펴봅니다.

  • 애플리케이션을 실행할 때 이벤트 로그를 만드는 대신 설치 관리자를 사용하여 애플리케이션을 설치할 때 이벤트 로그를 만듭니다. 애플리케이션을 제거할 때 설치 관리자가 이벤트 로그를 삭제합니다. 자세한 내용은 EventLogInstaller를 참조하세요.

참고하십시오