다음을 통해 공유


Visual C++ 프로젝트 속성 작업

이 항목에서는 Microsoft.VisualStudio.VCProjectEngine.dll의 인터페이스(특히 IVCRulePropertyStorage)를 사용하여 Visual C++ 프로젝트 속성 및 프로젝트 항목 속성을 가져오고 설정하는 방법에 대해 설명합니다. Visual C++ 프로젝트 속성은 GetProperty에서 사용할 수 없으며 여러 버전 간의 안정성이 유지되지 않으므로 이러한 인터페이스를 사용하는 것이 좋습니다.

Visual C++ 프로젝트 속성은 %ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\V120\1033\의 파일에서 정의됩니다. 예를 들어 general.xml은 일반 프로젝트 속성을 포함하고 debugger_general.xml은 일반 디버거 속성을 포함하는 방식입니다. IVCRulePropertyStorage 인터페이스를 사용하여 이러한 파일 중 하나가 있는 속성만 읽고 쓸 수 있습니다.

Tool 속성에서 Visual C++ 프로젝트 항목 속성을 설정하고 가져옵니다.

각 파일 항목 종류는 서로 다른 속성 집합을 포함합니다. Visual Studio 솔루션 탐색기에서 파일의 항목 종류를 확인하려면 해당 파일의 바로 가기 메뉴를 열고 속성을 선택합니다. 예를 들어 .cpp 파일의 항목 종류는 C/C++ 컴파일러로 표시됩니다. 지정된 항목 종류의 모든 속성을 확인하는 방법은 다음과 같습니다.

  1. %ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\V120\1033\ 디렉터리에서 항목 종류 표시 이름을 검색합니다. 예를 들어 "C/C++ 컴파일러"를 검색하면 ProjectItemsSchema.xml 파일에는 해당 항목 종류의 이름이 CICompile임이 표시됩니다.

  2. 해당 항목 종류에 대한 규칙 파일을 찾으려면 같은 디렉터리를 검색합니다. 이 경우 ClCompile은 관련이 없는 여러 .targets 및 .props 파일을 표시하므로 .xml 파일만 검색하도록 제한할 수 있습니다. ClCompile 항목 종류에 대한 규칙 파일은 cl.xml입니다.

  3. 찾으려는 속성에 대한 규칙 파일을 검색합니다. 표시 이름이 Additional Include Directories인 속성의 속성 이름이 AdditionalIncludeDirectories인 경우를 예로 들 수 있습니다.

  4. 규칙 파일은 지정된 속성이 유지되는 위치도 결정합니다. ClCompile 항목 종류와 연결된 속성은 프로젝트 파일에 유지됩니다. 이 속성은 Persistence 특성에서 확인할 수 있습니다. 변경한 속성 값은 프로젝트 파일에 유지됩니다.

Visual C++ 속성 페이지를 사용 및 확장하는 방법에 대한 자세한 내용은 다음 문서를 참조하세요. 이러한 문서에서는 Visual Studio 2010에 대한 설명을 제공하지만 프로젝트 속성에 대한 정보는 계속 유효합니다.

다음 코드의 작동 방식을 확인하려는 경우 프로젝트 속성 테스트라는 메뉴 명령이 있는 TestVCProjectProperties라는 VSPackage에 코드를 통합할 수 있습니다. 이를 수행하는 방법에 대한 자세한 내용은 Visual Studio 패키지 템플릿을 사용 하 여 연습: 메뉴 명령 만들기을 참조하십시오.

Visual C++ 프로젝트 속성 가져오기 및 설정

  1. 프로젝트 속성 대화 상자의 확장 탭에서 Microsoft.VisualStudio.VCProjectEngine에 대한 참조를 추가하고 프레임워크 탭에서 System.Windows.Forms에 대한 참조를 추가합니다.

  2. TestVCProjectPropertiesPackage.cs 파일을 열고 다음 using 지시문을 추가합니다.

    using EnvDTE;
    using EnvDTE80;
    using System.Windows.Forms;
    using Microsoft.VisualStudio.VCProjectEngine;
    
  3. 응용 프로그램 개체(여기서는 DTE2)에 대한 참조를 TestVCProjectPropertiesPackage 클래스에 추가하고 Initialize 메서드에서 해당 참조를 인스턴스화합니다.

    public sealed class TestProjectPropertiesPackage : Package
    {
        DTE2 dte2;
        . . .
        protected override void Initialize()
        {
            Debug.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
            base.Initialize();
    
            // Add command handlers for the menu (commands must exist in the .vsct file)
            OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
            if ( null != mcs )
            {
                // Create the command for the menu item.
                CommandID menuCommandID = new CommandID(GuidList.guidTestProjectPropertiesCmdSet, (int)PkgCmdIDList.cmdidMyCommand);
                MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID );
                mcs.AddCommand( menuItem );
            }
    
            dte2 = (DTE2)GetService(typeof(DTE));
        }
    }
    
  4. MenuItemCallback 메서드에서 기존 코드를 제거하고 열린 프로젝트를 가져오는 코드를 추가합니다. 프로젝트가 실제로 열려 있는지 확인해야 합니다.

    private void MenuItemCallback(object sender, EventArgs e) 
    {
        VCProject prj; 
        Projects projColl = dte2.Solution.Projects; 
    
        if (projColl.Count == 0) 
        {
            MessageBox.Show("You must have a project open in the experimental instance."); 
            return; 
        }
        if (projColl.Count > 0) 
        {
            // To be filled in later
        }
    }
    
  5. 첫 번째 프로젝트를 가져온 다음 Win32|Debug라는 프로젝트 구성을 찾습니다.

    private void MenuItemCallback(object sender, EventArgs e) 
    {
        VCProject prj; 
        Projects projColl = dte2.Solution.Projects; 
    
        if (projColl.Count == 0) 
        {
            MessageBox.Show("You must have a project open in the experimental instance."); 
            return; 
        }
        if (projColl.Count > 0) 
        {
            prj = (VCProject)dte2.Solution.Projects.Item(1).Object;
             VCConfiguration config = prj.Configurations.Item("Debug|Win32");
        }
    }
    
  6. 이 단계에서는 ConfigurationDirectories 규칙에서 IncludePath 속성을 가져오고 D:\Include를 현재 값에 추가합니다.

    참고

    두 메서드 중 하나를 사용하여 속성 값을 가져올 수 있습니다.GetUnevaluatedPropertyValue 메서드는 $(SolutionDir) 등의 속성을 평가하지 않고 값을 가져오며 GetEvaluatedPropertyValue 메서드는 이러한 속성을 확장합니다.

    private void MenuItemCallback(object sender, EventArgs e) 
    {
        VCProject prj; 
        Projects projColl = dte2.Solution.Projects; 
    
        if (projColl.Count == 0) 
        {
            MessageBox.Show("You must have a project open in the experimental instance."); 
            return; 
        }
        if (projColl.Count > 0) 
        {
            prj = (VCProject)dte2.Solution.Projects.Item(1).Object;
             VCConfiguration config = prj.Configurations.Item("Debug|Win32");
    
             IVCRulePropertyStorage rule = config.Rules.Item("ConfigurationDirectories") as IVCRulePropertyStorage;
             string rawValue = rule.GetUnevaluatedPropertyValue("IncludePath");
             string evaluatedValue = rule.GetEvaluatedPropertyValue("IncludePath");
             rule.SetPropertyValue("IncludePath", rawValue + "D:\\Include;");
    
             // Get the new property value
             MessageBox.Show(rule.GetUnevaluatedPropertyValue("IncludePath"));
        }
    }
    
  7. 솔루션을 빌드하고 디버깅을 시작합니다. 빌드는 실험적 인스턴스라는 두 번째 Visual Studio 인스턴스에 표시됩니다. 실험적 인스턴스에서 Visual C++ 프로젝트를 엽니다. 메뉴 모음에서 도구, 프로젝트 속성 테스트를 차례로 선택합니다. 그러면 대화 상자에 다음 값이 표시됩니다. $(VC_IncludePath);$(WindowsSDK_IncludePath);D:\Include;D:\Include;

Visual C++ 프로젝트 항목 속성 가져오기 및 설정

  1. 이전 절차에서 만든 TestVCProjectProperties 프로젝트에서 MenuItemCallback 메서드로 이동한 후에 다음 코드를 추가하여 프로젝트에서 .cpp 파일을 찾고 Additional Include Directories 속성을 가져온 다음 D:\Include로 설정합니다. 그런 후에 새 값이 표시되는 대화 상자를 표시합니다.

    private void MenuItemCallback(object sender, EventArgs e)
    {
        VCProject prj;
        Projects projColl = dte2.Solution.Projects;
    
        if (projColl.Count == 0)
        {
            MessageBox.Show("You must have a project open in the experimental instance.");
            return;
        }
        if (projColl.Count > 0)
        {
            prj = (VCProject)dte2.Solution.Projects.Item(1).Object;
    
            VCConfiguration config = prj.Configurations.Item("Debug|Win32");
            IVCRulePropertyStorage rule = config.Rules.Item("ConfigurationDirectories") as IVCRulePropertyStorage;
             string rawValue = rule.GetUnevaluatedPropertyValue("IncludePath");
             string evaluatedValue = rule.GetEvaluatedPropertyValue("IncludePath");
             rule.SetPropertyValue("IncludePath", rawValue + "D:\\Include;");
    
             // Get the new property value
             MessageBox.Show(rule.GetUnevaluatedPropertyValue("IncludePath"));
    
            foreach (VCFile file in prj.Files)
            {
                if (file.FileType == eFileType.eFileTypeCppCode)
                {
                    VCFileConfiguration fileConfig = file.FileConfigurations.Item("Debug|Win32") as VCFileConfiguration;
                    IVCRulePropertyStorage fileRule = fileConfig.Tool as IVCRulePropertyStorage;
                    string evaluatedValue2 = fileRule.GetEvaluatedPropertyValue("AdditionalIncludeDirectories");
                    fileRule.SetPropertyValue("AdditionalIncludeDirectories", "D:\\Include");
                    MessageBox.Show(fileRule.GetEvaluatedPropertyValue("AdditionalIncludeDirectories"));
                }
            }  
        }
    }
    
  2. 솔루션을 빌드하고 디버깅을 시작합니다. 실험적 인스턴스에서 Visual C++ 프로젝트를 엽니다. 메뉴 모음에서 도구, 프로젝트 속성 테스트를 차례로 선택합니다. 첫 번째 대화 상자에는 $(VC_IncludePath);$(WindowsSDK_IncludePath);D:\Include;D:\Include; 값이 표시되고 두 번째 대화 상자에는 D:\Include 값이 표시됩니다.

  3. 이 값이 유지되는 위치를 확인하려면 실험적 인스턴스의 열린 프로젝트에 모든 파일을 저장합니다. 새 값이 .vcxproj 파일에 표시됩니다.

속성 값 변경 내용 검색

  1. ItemPropertyChange2 이벤트를 구독하면 Visual C++ 프로젝트 속성 또는 프로젝트 항목 속성에 다른 값이 지정되는 경우를 검색할 수 있습니다.

    TestVCProjectPropertiesPackage 클래스에서 이 이벤트에 대한 이벤트 처리기를 만듭니다. 여기서 처리기는 변경된 속성을 보여주는 대화 상자만 표시합니다.

    void OnVCProjectEngineItemPropertyChange(Object item, string strPropertySheet, string strItemType, string PropertyName)
    {
        MessageBox.Show("got property change event for " + PropertyName);
    }
    
  2. Initialize 메서드에서 응용 프로그램 개체 이벤트로부터 VCProjectEngineEventsObject를 가져온 후 방금 만든 이벤트 처리기를 추가합니다.

    protected override void Initialize()
    {
        Debug.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
        base.Initialize();
    
        // Add the command handlers for the menu (commands must exist in the .vsct file)
        OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
        if ( null != mcs )
        {
            // Create the command for the menu item
             CommandID menuCommandID = new CommandID(GuidList.guidTestProjectPropertiesCmdSet, (int)PkgCmdIDList.cmdidMyCommand);
            MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID );
            mcs.AddCommand( menuItem );
        }
    
        dte2 = (DTE2)GetService(typeof(DTE));
        VCProjectEngineEvents vcProjectEvents = dte2.Events.GetObject("VCProjectEngineEventsObject") as VCProjectEngineEvents;
    
        vcProjectEvents.ItemPropertyChange2 += new _dispVCProjectEngineEvents_ItemPropertyChange2EventHandler(OnVCProjectEngineItemPropertyChange);
    }
    
  3. 솔루션을 빌드하고 디버깅을 시작합니다. 실험적 인스턴스에서 Visual C++ 프로젝트를 엽니다. 메뉴 모음에서 도구, 프로젝트 속성 테스트를 차례로 선택합니다. 첫 번째 대화 상자에는 $(VC_IncludePath);$(WindowsSDK_IncludePath);D:\Include;D:\Include; 값이, 두 번째 대화 상자에는 Got property change event for IncludePath 값이, 세 번째 대화 상자에는 D:\Include 값이, 네 번째 대화 상자에는 Got property change event for AdditionalIncludeDirectories 값이 표시됩니다.

    참고

    이 코드의 변경 내용이 유지된 후에는 속성 변경 이벤트를 가져올 수 없습니다.이벤트를 확인하려면 속성 값을 다르게 변경합니다.