Visual Studio를 사용하여 .net Windows 서비스 용 설치 관리자를 만드는 방법


답변:


227

서비스 프로젝트에서 다음을 수행하십시오.

  1. 솔루션 탐색기에서 services .cs 파일을 두 번 클릭하십시오. 모두 회색 인 화면이 나타나고 도구 상자에서 항목을 드래그하는 것에 대해 이야기합니다.
  2. 그런 다음 회색 영역을 마우스 오른쪽 버튼으로 클릭하고 설치 프로그램 추가를 선택하십시오. 설치 프로그램 프로젝트 파일이 프로젝트에 추가됩니다.
  3. 그런 다음 ProjectInstaller.cs (serviceProcessInstaller1 및 serviceInstaller1)의 디자인보기에 2 개의 구성 요소가 있습니다. 그런 다음 필요한 서비스 이름 및 사용자와 같은 속성을 설정해야합니다.

이제 설정 프로젝트를 만들어야합니다. 가장 좋은 방법은 설정 마법사를 사용하는 것입니다.

  1. 솔루션을 마우스 오른쪽 단추로 클릭하고 새 프로젝트를 추가하십시오 : 추가> 새 프로젝트> 설정 및 배치 프로젝트> 설정 마법사

    ㅏ. Visual Studio 버전마다 약간 다를 수 있습니다. 비. Visual Studio 2010의 위치 : 템플릿 설치> 기타 프로젝트 유형> 설치 및 배포> Visual Studio Installer

  2. 두 번째 단계에서 "Windows 응용 프로그램 용 설치 프로그램 만들기"를 선택하십시오.

  3. 세 번째 단계에서 "Primary output from ..."을 선택하십시오.

  4. 클릭하여 완료합니다.

다음으로 올바른 출력이 포함되도록 설치 프로그램을 편집하십시오.

  1. 솔루션 탐색기에서 설정 프로젝트를 마우스 오른쪽 버튼으로 클릭하십시오.
  2. 보기> 사용자 정의 조치를 선택하십시오. (VS2008에서는보기> 편집기> 사용자 지정 작업 일 수 있음)
  3. 사용자 정의 조치 트리에서 설치 조치를 마우스 오른쪽 단추로 클릭하고 '사용자 정의 조치 추가 ...'를 선택하십시오.
  4. "프로젝트에서 항목 선택"대화 상자에서 응용 프로그램 폴더를 선택하고 확인을 클릭하십시오.
  5. "1 차 출력 ..."옵션을 선택하려면 확인을 클릭하십시오. 새로운 노드가 생성되어야합니다.
  6. 커밋, 롤백 및 제거 작업에 대해 4-5 단계를 반복하십시오.

솔루션에서 설치 프로그램 프로젝트를 마우스 오른쪽 단추로 클릭하고 등록 정보를 선택하여 설치 프로그램 출력 이름을 편집 할 수 있습니다. '출력 파일 이름 :'을 원하는 것으로 변경하십시오. 뿐만 아니라 설치 프로젝트를 선택하고 속성 창에서 찾고, 당신은을 편집 할 수 있습니다 Product Name, Title, Manufacturer, 등 ...

다음으로 설치 프로그램을 빌드하면 MSI와 setup.exe가 생성됩니다. 서비스 배포에 사용할 것을 선택하십시오.


37
@ El Ronnoco, 게시하기 오래 전에 답변을 받았습니다. 나는 항상 6-12 개월마다 찾아야하기 때문에 여기에 문서화하고 싶었습니다 (그리고 쉽게 찾을 수 없었습니다). 이제 모든 사람이 쉽게 검색 할 수 있고 빠르게 찾을 수 있습니다. :)
Kelsey

1
불행히도, 그것은 또한 잘못된 대답입니다. 그렇습니다.이 책을 MSDN과 MSDN에서 찾을 수 있지만 Microsoft의 한 그룹이 Microsoft의 다른 그룹과 대화하지 않고 이미 해결 된 문제에 대한 열등한 해결책을 찾은 경우입니다. 자세한 내용은 blog.iswix.com/2006/07/msi-vs-net.html 을 참조하십시오.
Christopher Painter

9
@Christopher Painter 2k5 이후로 MS 설치 프로그램을 사용해 왔으며 문제가 없었습니다. 당신이 그것에 동의하고 그것을 '반 패턴 (anti-pattern)'이라고 생각하는지의 여부는이 질문의 요점이 아닙니다. 그것은 어떻게 x로 y를하는지, b로 어떻게합니까? 질문을 게시했을 때 문서화 목적이었습니다.
Kelsey

3
그럼 당신은 6 년 동안 운이 좋았을뿐입니다. 당신은 읽을 수 있습니다 : robmensching.com/blog/posts/2007/4/19/…
Christopher Painter

1
당신이 얻을 경우 Service name contains invalid characters, is empty, or is too long (max length = 80)설치 프로그램을 추가 할 때 오류를 마우스 오른쪽, 다시 회색 영역을 클릭하고 속성으로 이동하여 서비스 이름 값이 설정되어 있는지 확인합니다.
wolfyuk

51

Kelsey의 첫 번째 단계에 따라 설치 프로그램 클래스를 서비스 프로젝트에 추가하지만 MSI 또는 setup.exe 설치 프로그램을 만드는 대신 서비스를 자동 설치 / 제거합니다. 내 서비스 중 하나에서 시작점으로 사용할 수있는 약간의 샘플 코드가 있습니다.

public static int Main(string[] args)
{
    if (System.Environment.UserInteractive)
    {
        // we only care about the first two characters
        string arg = args[0].ToLowerInvariant().Substring(0, 2);

        switch (arg)
        {
            case "/i":  // install
                return InstallService();

            case "/u":  // uninstall
                return UninstallService();

            default:  // unknown option
                Console.WriteLine("Argument not recognized: {0}", args[0]);
                Console.WriteLine(string.Empty);
                DisplayUsage();
                return 1;
        }
    }
    else
    {
        // run as a standard service as we weren't started by a user
        ServiceBase.Run(new CSMessageQueueService());
    }

    return 0;
}

private static int InstallService()
{
    var service = new MyService();

    try
    {
        // perform specific install steps for our queue service.
        service.InstallService();

        // install the service with the Windows Service Control Manager (SCM)
        ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
    }
    catch (Exception ex)
    {
        if (ex.InnerException != null && ex.InnerException.GetType() == typeof(Win32Exception))
        {
            Win32Exception wex = (Win32Exception)ex.InnerException;
            Console.WriteLine("Error(0x{0:X}): Service already installed!", wex.ErrorCode);
            return wex.ErrorCode;
        }
        else
        {
            Console.WriteLine(ex.ToString());
            return -1;
        }
    }

    return 0;
}

private static int UninstallService()
{
    var service = new MyQueueService();

    try
    {
        // perform specific uninstall steps for our queue service
        service.UninstallService();

        // uninstall the service from the Windows Service Control Manager (SCM)
        ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
    }
    catch (Exception ex)
    {
        if (ex.InnerException.GetType() == typeof(Win32Exception))
        {
            Win32Exception wex = (Win32Exception)ex.InnerException;
            Console.WriteLine("Error(0x{0:X}): Service not installed!", wex.ErrorCode);
            return wex.ErrorCode;
        }
        else
        {
            Console.WriteLine(ex.ToString());
            return -1;
        }
    }

    return 0;
}

1
호기심으로 인해 자체 설치 / 제거 서비스를 사용하면 어떤 이점이 있습니까? 서비스가 자체적으로 설치되는 경우 서비스를 처음 시작하여 처음에 설치할 수 있도록하려면 어떻게합니까? 서비스를 설치하지 않고 시작하는 메커니즘이 있다면 왜 설치를 귀찮게합니까?
Kiley Naro

3
@Christopher-안 그렇습니다. 내 솔루션은 소프트웨어 배포에 사용할 전체 설치 프로그램을 대체하지 않습니다. 무인 키오스크로 임베디드 PC를 구동하는 소프트웨어를 작성하는 등 일부 상황에서 작동하는 다른 옵션을 제시하고 있습니다.

4
프로덕션 시스템에 설치하는 경우 관리자 권한으로 실행해야합니다. / i 매개 변수를 사용하여 EXE 파일을 호출하는 BAT 파일을 만들었지 만 BAT 파일을 관리자로 실행했지만 프로덕션 환경에서는 작동하지 않았습니다. 관리자로 명령 줄 프롬프트를 열고 BAT 파일을 사용하지 않고 EXE 파일 / i를 명시 적으로 호출해야했습니다. 적어도 그것은 Windows Server 2012에서 나에게 일어났습니다.
Francisco Goldenstein

1
RE : 명령 행에 출력이 없습니다. VS 2017 Community를 사용하여 새 서비스 프로젝트의 기본값은 출력 유형 : Windows Application및 시작 객체 : (none)입니다. 출력 유형을로 변경 Console Application하고 시작 객체를 설정해야했습니다 (예 :) myservice.Program. 내가 모르는 파급 효과가있을 경우 조언하십시오.
Jonathan

1
예제 코드에 오타가 있습니까? 세 가지 차이점 서비스 (CSMessageQueueService, MyService, MyQueueService)가있는 이유는 무엇입니까?
닐스

27

Kelsey와 Brendan 솔루션도 Visual Studio 2015 Community에서 작동하지 않습니다.

설치 프로그램으로 서비스를 작성하는 방법에 대한 간단한 단계는 다음과 같습니다.

  1. Visual Studio를 실행하고 File->New->Project
  2. '설치된 템플릿 검색 '에서 '서비스'를 입력하고 .NET Framework 4를 선택하십시오.
  3. 'Windows 서비스'를 선택하십시오. 이름과 위치를 입력하십시오. 를 누릅니다 OK.
  4. Service1.cs를 두 번 클릭하고 디자이너를 마우스 오른쪽 단추로 클릭 한 다음 'Add Installer'를 선택하십시오.
  5. ProjectInstaller.cs를 두 번 클릭하십시오. serviceProcessInstaller1의 경우 특성 탭을 열고 '계정'특성 값을 'LocalService'로 변경하십시오. serviceInstaller1의 경우 'ServiceName'을 변경하고 'StartType'을 'Automatic'으로 설정하십시오.
  6. serviceInstaller1을 두 번 클릭하십시오. Visual Studio가 serviceInstaller1_AfterInstall이벤트를 만듭니다 . 코드 작성 :

    private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
    {
        using (System.ServiceProcess.ServiceController sc = new 
        System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName))
        {
            sc.Start();
        }
    }
    
  7. 솔루션을 구축하십시오. 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 '파일 탐색기에서 폴더 열기'를 선택하십시오. bin \ Debug로 이동하십시오 .

  8. 아래 스크립트를 사용하여 install.bat를 작성하십시오.

    :::::::::::::::::::::::::::::::::::::::::
    :: Automatically check & get admin rights
    :::::::::::::::::::::::::::::::::::::::::
    @echo off
    CLS 
    ECHO.
    ECHO =============================
    ECHO Running Admin shell
    ECHO =============================
    
    :checkPrivileges 
    NET FILE 1>NUL 2>NUL
    if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges ) 
    
    :getPrivileges 
    if '%1'=='ELEV' (shift & goto gotPrivileges)  
    ECHO. 
    ECHO **************************************
    ECHO Invoking UAC for Privilege Escalation 
    ECHO **************************************
    
    setlocal DisableDelayedExpansion
    set "batchPath=%~0"
    setlocal EnableDelayedExpansion
    ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\OEgetPrivileges.vbs" 
    ECHO UAC.ShellExecute "!batchPath!", "ELEV", "", "runas", 1 >> "%temp%\OEgetPrivileges.vbs" 
    "%temp%\OEgetPrivileges.vbs" 
    exit /B 
    
    :gotPrivileges 
    ::::::::::::::::::::::::::::
    :START
    ::::::::::::::::::::::::::::
    setlocal & pushd .
    
    cd /d %~dp0
    %windir%\Microsoft.NET\Framework\v4.0.30319\InstallUtil /i "WindowsService1.exe"
    pause
    
  9. 파일 uninstall.bat 만들기 (펜 ULT 라인의 변화 /i/u)
  10. 서비스를 설치하고 시작하려면 install.bat를 실행하고, uninstall.bat를 중지하고 설치 제거하십시오.

14

VS2017의 경우 "Microsoft Visual Studio 2017 설치 관리자 프로젝트"VS 확장을 추가해야합니다. 추가 Visual Studio Installer 프로젝트 템플릿이 제공됩니다. https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.MicrosoftVisualStudio2017InstallerProjects#overview

Windows 서비스를 설치하려면 새 설치 마법사 유형 프로젝트를 추가하고 Kelsey의 답변 https://stackoverflow.com/a/9021107/1040040 의 단계를 수행 하십시오.


1

InstallUtil 클래스 (ServiceInstaller)는 Windows Installer 커뮤니티에서 안티 패턴으로 간주됩니다. Windows Installer가 기본적으로 서비스 지원을 제공한다는 사실을 무시하고 깨지기 쉬운 프로세스로 인해 바퀴를 다시 발명했습니다.

Visual Studio 배포 프로젝트 (다음 Visual Studio 릴리스에서 높이 평가되지 않거나 더 이상 사용되지 않음)는 서비스를 기본적으로 지원하지 않습니다. 그러나 그들은 병합 모듈을 소비 할 수 있습니다. 따라서이 블로그 기사를보고 서비스를 표현할 수있는 Windows Installer XML을 사용하여 병합 모듈을 생성 한 다음 VDPROJ 솔루션에서 해당 병합 모듈을 사용하는 방법을 이해합니다.

Windows Installer XML을 사용하여 InstallShield 기능 보강-Windows 서비스

IsWiX Windows 서비스 자습서

IsWiX Windows 서비스 비디오


1
이전 Visual Studio에는 쉬운 설치 관리자가 포함 된 배포 프로젝트가있었습니다. 이제 타사 소프트웨어 구성 요소를 구입해야합니까?
Alexey Obukhov

@AlexeyObukhov Wix를 무료로 사용할 수 있습니다. VS 자체가 사용하는 것이지만 Wix의 문제는 거의 수직 학습 곡선 인 Git의 문제와 같습니다.
Alan B
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.