연습: 사용자 지정 작업을 사용하여 설치 시 이진 코드를 네이티브 코드에 컴파일

사용자 지정 작업을 정의하여 설치 후에 실행할 명령을 지정할 수 있습니다. 예를 들어 이 연습에서는 사용자 지정 작업을 정의하고 EXE의 경로 이름을 CustomActionData 속성에 전달하여 응용 프로그램이 설치된 후 실행 파일을 네이티브 코드로 컴파일합니다.

참고

다음 지침처럼 컴퓨터에서 Visual Studio 사용자 인터페이스 요소 일부에 대한 이름이나 위치를 다르게 표시할 수 있습니다. 이러한 요소는 사용하는 Visual Studio 버전 및 설정에 따라 결정됩니다. 자세한 내용은 Visual Studio 설정을 참조하십시오.

배포할 웹 브라우저 응용 프로그램을 만들려면

  1. 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트를 클릭합니다.

  2. Windows Forms 응용 프로그램을 클릭합니다.

  3. 이름에 BrowserSample을 입력하고 확인을 클릭합니다.

  4. 보기 메뉴에서 도구 상자를 클릭합니다.

  5. 모든 Windows Forms를 확장하고 Panel 컨트롤을 폼의 왼쪽 위로 끕니다.

  6. 폼 디자이너에서 TextBox 컨트롤과 Button 컨트롤을 Panel 컨트롤로 끕니다.

  7. 폼 디자이너에서 WebBrowser 컨트롤을 Panel 아래로 끕니다.

  8. 모든 컨트롤에 맞게 폼의 크기를 확장합니다.

  9. 폼 디자이너에서 Panel 컨트롤을 클릭합니다.

  10. 속성 창에서 레이아웃 아래의 Dock 속성을 위쪽으로 변경합니다.

  11. 폼 디자이너에서 WebBrowser 컨트롤을 클릭합니다.

  12. 속성 창에서 레이아웃 아래의 Dock 속성을 채우기로 변경합니다.

  13. 폼 디자이너에서 Button 컨트롤을 클릭합니다.

  14. 속성 창에서 모양 아래의 Text 속성을 이동으로 변경합니다.

  15. Form, Panel, Textbox, ButtonWebBrowser의 크기를 원하는 대로 조정합니다.

  16. 폼 디자이너에서 이동 단추를 두 번 클릭합니다.

    Form1 코드 파일의 코드 뷰가 나타납니다.

  17. 응용 프로그램에 웹 검색 기능을 추가하는 다음 코드를 추가합니다. TextBox 컨트롤의 텍스트는 WebBrowser 컨트롤의 주소 표시줄이며, 이동 단추를 클릭하면 작업이 수행됩니다.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        WebBrowser1.Navigate(TextBox1.Text)
    End Sub
    
    private void button1_Click(object sender, EventArgs e)
    {
        webBrowser1.Navigate(textBox1.Text);
    }
    
  18. 브라우저를 테스트하려면 F5 키를 누릅니다.

    폼이 열립니다.

  19. 텍스트 상자에 http://www.microsoft.com을 입력한 다음 이동을 클릭합니다.

    Microsoft 웹 사이트가 나타납니다.

사용자 지정 작업 클래스를 만들려면

  1. 파일 메뉴에서 추가를 가리킨 다음 새 프로젝트를 클릭합니다.

  2. 새 프로젝트 추가 대화 상자에서 Windows를 클릭한 다음 클래스 라이브러리를 클릭합니다.

  3. 이름 상자에 NGenCustomAction을 입력한 다음 확인을 클릭합니다.

  4. 프로젝트 메뉴에서 새 항목 추가를 클릭합니다.

  5. 새 항목 추가 대화 상자에서 일반을 클릭한 다음 설치 관리자 클래스를 클릭합니다. 이름 상자에 NGenCustomAction을 입력한 다음 추가를 클릭합니다.

    참고

    설치 관리자 클래스를 추가했는지 확인합니다. 그렇지 않으면 코드 파일에 필요한 using 문이 포함되지 않습니다.

  6. 솔루션 탐색기에서 NGenCustomAction 프로젝트에 있는 Class1 코드 파일을 삭제합니다.

사용자 지정 작업에 코드를 추가하려면

  1. 솔루션 탐색기 또는 디자인 화면에서 NGenCustomAction 코드 파일을 마우스 오른쪽 단추로 클릭한 다음 코드 보기를 클릭하여 코드 편집기를 엽니다. 모듈의 맨 위에 다음 코드를 추가합니다.

    Imports System.IO
    Imports System.Diagnostics
    
    using System.IO;
    using System.Diagnostics;
    
  2. System.Configuration.Install.Installer 클래스에서 상속하도록 클래스 선언을 업데이트합니다.

    Inherits System.Configuration.Install.Installer
    
    : System.Configuration.Install.Installer
    
  3. NGenCustomAction 코드 파일에서 다음 도우미 메서드를 추가하여 어셈블리의 네이티브 이미지 코드 파일을 생성합니다.

        <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _
    Private Sub ngenCA(ByVal savedState As System.Collections.IDictionary, ByVal ngenCommand As String)
            Dim argsArray As [String]()
    
            If String.Compare(ngenCommand, "install", StringComparison.OrdinalIgnoreCase) = 0 Then
                Dim args As [String] = Context.Parameters("Args")
                If [String].IsNullOrEmpty(args) Then
                    Throw New InstallException("No arguments specified")
                End If
    
                Dim separators As Char() = {";"c}
                argsArray = args.Split(separators)
                'It is Ok to 'ngen uninstall' assemblies which were not installed
                savedState.Add("NgenCAArgs", argsArray)
            Else
                argsArray = DirectCast(savedState("NgenCAArgs"), [String]())
            End If
    
            ' Gets the path to the Framework directory.
            Dim fxPath As String = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
    
            For i As Integer = 0 To argsArray.Length - 1
                Dim arg As String = argsArray(i)
                ' Quotes the argument, in case it has a space in it.
                arg = """" & arg & """"
    
                Dim command As String = (ngenCommand & " ") + arg
    
                Dim si As New ProcessStartInfo(Path.Combine(fxPath, "ngen.exe"), command)
                si.WindowStyle = ProcessWindowStyle.Hidden
    
                Dim p As Process
    
                Try
                    Context.LogMessage((">>>>" & Path.Combine(fxPath, "ngen.exe ")) + command)
                    p = Process.Start(si)
                    p.WaitForExit()
                Catch ex As Exception
                    Throw New InstallException("Failed to ngen " & arg, ex)
                End Try
            Next
        End Sub
    
            [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
            private void ngenCA(System.Collections.IDictionary savedState, string ngenCommand)
            {
                String[] argsArray;
    
                if (string.Compare(ngenCommand, "install", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    String args = Context.Parameters["Args"];
                    if (String.IsNullOrEmpty(args))
                    {
                        throw new InstallException("No arguments specified");
                    }
    
                    char[] separators = { ';' };
                    argsArray = args.Split(separators);
                    savedState.Add("NgenCAArgs", argsArray); //It is Ok to 'ngen uninstall' assemblies which were not installed
                }
                else
                {
                    argsArray = (String[])savedState["NgenCAArgs"];
                }
    
                // Gets the path to the Framework directory.
                string fxPath = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
    
                for (int i = 0; i < argsArray.Length; ++i)
                {
                    string arg = argsArray[i];
                    // Quotes the argument, in case it has a space in it.
                    arg = "\"" + arg + "\"";
    
                    string command = ngenCommand + " " + arg;
    
                    ProcessStartInfo si = new ProcessStartInfo(Path.Combine(fxPath, "ngen.exe"), command);
                    si.WindowStyle = ProcessWindowStyle.Hidden;
    
                    Process p;
    
                    try
                    {
                        Context.LogMessage(">>>>" + Path.Combine(fxPath, "ngen.exe ") + command);
                        p = Process.Start(si);
                        p.WaitForExit();
                    }
                    catch (Exception ex)
                    {
                        throw new InstallException("Failed to ngen " + arg, ex);
                    }
                }
            }
    
    
  4. NGenCustomAction 코드 파일에서 다음 프로시저를 추가하여 기본 클래스의 Install, Commit, Rollback 및 Uninstall 프로시저를 재정의합니다.

    <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _
    Public Overloads Overrides Sub Install(ByVal savedState As System.Collections.IDictionary)
        MyBase.Install(savedState)
        Context.LogMessage(">>>> ngenCA: install")
        ngenCA(savedState, "install")
    End Sub
    
    <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _
    Public Overrides Sub Commit(ByVal savedState As System.Collections.IDictionary)
        MyBase.Commit(savedState)
        Context.LogMessage(">>>> ngenCA: commit")
    End Sub
    
    <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _
    Public Overloads Overrides Sub Uninstall(ByVal savedState As System.Collections.IDictionary)
        MyBase.Uninstall(savedState)
        Context.LogMessage(">>>> ngenCA: uninstall")
        ngenCA(savedState, "uninstall")
    End Sub
    
    <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _
    Public Overloads Overrides Sub Rollback(ByVal savedState As System.Collections.IDictionary)
        MyBase.Rollback(savedState)
        Context.LogMessage(">>>> ngenCA: rollback")
        ngenCA(savedState, "uninstall")
    End Sub
    
    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Install(System.Collections.IDictionary savedState)
    {
        base.Install(savedState);
        Context.LogMessage(">>>> ngenCA: install");
        ngenCA(savedState, "install");
    }
    
    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Commit(IDictionary savedState)
    {
        base.Commit(savedState);
        Context.LogMessage(">>>> ngenCA: commit");
    }
    
    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Uninstall(System.Collections.IDictionary savedState)
    {
        base.Uninstall(savedState);
        Context.LogMessage(">>>> ngenCA: uninstall");
        ngenCA(savedState, "uninstall");
    }
    
    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Rollback(System.Collections.IDictionary savedState)
    {
        base.Rollback(savedState);
        Context.LogMessage(">>>> ngenCA: rollback");
        ngenCA(savedState, "uninstall");
    }
    

브라우저 샘플 응용 프로그램에 대한 배포 프로젝트를 추가하려면

  1. 파일 메뉴에서 추가를 가리킨 다음 새 프로젝트를 클릭합니다.

  2. 새 프로젝트 추가 대화 상자에서 기타 프로젝트 형식설치 및 배포 프로젝트를 차례로 확장하고 Visual Studio 설치 관리자를 클릭한 다음 설치 프로젝트를 클릭합니다.

  3. 이름 상자에 브라우저 샘플 설치 관리자를 입력한 다음 확인을 클릭합니다.

  4. 파일 시스템 편집기에서 응용 프로그램 폴더를 선택합니다. 작업 메뉴에서 추가를 클릭합니다.

    프로젝트 출력 그룹 추가 대화 상자가 나타납니다.

  5. 프로젝트 드롭다운 콤보 상자에서 브라우저 샘플을 선택하고 프로젝트 출력을 클릭한 다음 확인을 클릭합니다.

  6. 파일 시스템 편집기에서 응용 프로그램 폴더를 선택합니다. 작업 메뉴에서 추가를 클릭합니다.

    프로젝트 출력 그룹 추가 대화 상자가 나타납니다.

  7. 프로젝트 드롭다운 콤보 상자에서 NGenCustomAction을 선택하고 프로젝트 출력을 클릭한 다음 확인을 클릭합니다.

설치 프로젝트에 NGEN 사용자 지정 작업을 추가하려면

  1. 솔루션 탐색기에서 브라우저 샘플 설치 관리자 프로젝트를 클릭합니다.

  2. 보기 메뉴에서 편집기를 가리킨 다음 사용자 지정 작업을 클릭합니다.

  3. 사용자 지정 작업 편집기에서 사용자 지정 작업 노드를 선택합니다.

  4. 작업 메뉴에서 사용자 지정 작업 추가를 클릭합니다.

  5. 프로젝트에서 항목 선택 대화 상자에서 응용 프로그램 폴더를 두 번 클릭한 다음 **NGenCustomAction의 기본 출력(활성)**을 클릭하고 확인을 클릭합니다.

    NGEN 사용자 지정 작업이 네 개의 사용자 지정 작업 노드 모두에 추가됩니다.

  6. 설치 노드에서 **NGenCustomAction의 기본 출력(활성)**을 클릭합니다.

  7. 속성 창에서 CustomActionData 속성을 /Args="[TARGETDIR]BrowserSample.exe"로 변경합니다. 큰따옴표(")로 묶어야 합니다.

    참고

    [TARGETDIR] 속성은 설치된 실행 파일의 위치입니다. 사용자 지정 작업은 ngen.exe를 사용하여 설치된 실행 파일을 네이티브 이미지로 변환합니다.

  8. 솔루션 탐색기에서 브라우저 샘플 설치 관리자 설치 프로젝트를 클릭합니다.

  9. 빌드 메뉴에서 브라우저 샘플 설치 관리자를 클릭합니다.

네이티브 코드 생성을 확인하려면

  1. 설치 폴더로 이동하고 BrowserSample.exe 파일을 찾습니다. 예를 들면 %PROGRAMFILES%\CompanyName\Brower Sample Installer\BrowserSample.exe와 같습니다.

  2. Visual Studio 명령 프롬프트에서 다음 코드를 실행하여 실행 파일이 네이티브 코드로 미리 컴파일되었는지 확인합니다.

    ngen.exe display FullPathToExe
    

    예를 들어 다음 명령을 실행할 수 있습니다.

    ngen.exe display "C:\Program Files (x86)\Microsoft\Browser Sample Installer\BrowserSample.exe"
    

    명령 출력이 나타납니다.

    Microsoft (R) CLR Native Image Generator - Version 4.0.21102.0
    Copyright (c) Microsoft Corporation.  All rights reserved.
    
    NGEN Roots:
    
    C:\Program Files (x86)\Microsoft\Browser Sample Installer\BrowserSample.exe
    
    NGEN Roots that depend on "c:\Program Files (x86)\Microsoft\Browser Sample Installer\BrowserSample.exe":
    
    C:\Program Files (x86)\Microsoft\Browser Sample Installer\BrowserSample.exe
    
    Native Images:
    
    BrowserSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null <debug>
    

    참고

    ngen.exe에서 네이티브 이미지를 표시하지 않는 경우 다음 디렉터리 중 하나에서 ngen 로그를 찾을 수 있습니다.

    %SystemRoot%\Microsoft.NET\Framework\v<CLR version> %SystemRoot%\Microsoft.NET\Framework64\v<CLR version>

    ngen.log 파일은 가장 최근의 문제 해결 로그입니다.

참고 항목

참조

CustomActionData 속성

Ngen.exe(네이티브 이미지 생성기)

개념

관리되는 실행 프로세스

기타 리소스

배포 시 사용자 지정 작업 관리