Condividi tramite


Uso delle proprietà di progetto in Visual C++

Vengono fornite informazioni sull'uso delle interfacce in Microsoft.VisualStudio.VCProjectEngine.dll, in particolare IVCRulePropertyStorage, per ottenere e impostare le proprietà del progetto Visual C++ e dei relativi elementi. L'uso di queste interfacce è consigliato perché le proprietà dei progetti Visual C++ non sono disponibili tramite GetProperty e la loro stabilità nelle diverse versioni non è garantita.

Le proprietà dei progetti Visual C++ sono definite nei file in %ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\V120\1033\. general.xml, ad esempio, contiene proprietà di progetto generiche, debugger_general.xml contiene proprietà generiche del debugger e così via. È possibile usare l'interfaccia IVCRulePropertyStorage per leggere e scrivere solo quelle proprietà per le quali uno di questi file esiste.

Le proprietà degli elementi di progetto di Visual C++ vengono ottenute e impostate dalla proprietà Tool.

I diversi tipi di elementi file hanno diversi set di proprietà. Per trovare il tipo di elemento di un file in Esplora soluzioni di Visual Studio, aprire il menu di scelta rapida per il file e scegliere Proprietà. Ad esempio, il tipo di elemento per un file con estensione cpp file viene visualizzato come Compilatore C/C++. Di seguito viene indicato come trovare tutte le proprietà di un determinato tipo di elemento:

  1. Cercare il nome visualizzato del tipo di elemento nella directory %ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\V120\1033\. Se ad esempio si cerca "Compilatore C/C++", il file ProjectItemsSchema.xml mostra che il nome dell'elemento corrispondente è ClCompile.

  2. Per trovare il file delle regole per quel tipo di elemento, cercarlo nella stessa directory. Nel caso specifico, poiché ClCompile è visualizzato in molti file .targets e .props non correlati, è possibile limitare la ricerca ai soli file .xml. Il file delle regole per l'elemento ClCompile è cl.xml.

  3. Cercare il file delle regole per la proprietà che si vuole trovare. La proprietà con il nome visualizzato Directory di inclusione aggiuntive, ad esempio, presenta il nome di proprietà AdditionalIncludeDirectories.

  4. Il file delle regole determina anche la posizione in cui una determinata proprietà è persistente. Le proprietà associate al tipo di elemento ClCompile sono persistenti nel file di progetto (cercare l'attributo Persistence). I valori delle proprietà modificati verranno resi persistenti nel file di progetto.

Per informazioni su come usare ed estendere le pagine delle proprietà di Visual C++, vedere gli articoli indicati di seguito, in cui, nonostante venga menzionato Visual Studio 2010, sono contenute informazioni ancora valide sulle proprietà dei progetti.

Per osservare il funzionamento del codice seguente, è possibile integrarlo in un VSPackage denominato TestVCProjectProperties che presenti un comando di menu denominato Test proprietà progetto. Per informazioni su come eseguire questa operazione, vedere procedura dettagliata: Creazione di un comando di menu utilizzando il modello importa pacchetto Visual Studio.

Recupero e impostazione delle proprietà dei progetti Visual C++

  1. Nella scheda Estensioni della finestra di dialogo Proprietà progetti aggiungere un riferimento a Microsoft.VisualStudio.VCProjectEngine, quindi nella scheda Framework aggiungere un riferimento a System.Windows.Forms.

  2. Aprire il file TestVCProjectPropertiesPackage.cs. Aggiungere le direttive using seguenti:

    using EnvDTE;
    using EnvDTE80;
    using System.Windows.Forms;
    using Microsoft.VisualStudio.VCProjectEngine;
    
  3. Aggiungere un riferimento all'oggetto Application, in questo caso DTE2, alla classe TestVCProjectPropertiesPackage e crearne un'istanza nel metodo 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. Rimuovere il codice esistente dal metodo MenuItemCallback. Aggiungere codice per ottenere i progetti aperti. Verificare che sia effettivamente aperto un progetto.

    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. Ottenere il primo progetto e trovare la configurazione di progetto denominata 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. In questo passaggio si ottiene la proprietà IncludePath dalla regola ConfigurationDirectories e si aggiunge D:\Include al valore attuale.

    Nota

    Per ottenere i valori delle proprietà è possibile usare uno di due metodi.Il metodo GetUnevaluatedPropertyValue ottiene il valore senza valutare alcuna proprietà, ad esempio $(SolutionDir), mentre il metodo GetEvaluatedPropertyValue espande tali proprietà.

    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. Compilare la soluzione e avviare il debug. La build viene visualizzata in una seconda istanza di Visual Studio nota come istanza sperimentale. Aprire un progetto Visual C++ nell'istanza sperimentale. Nella barra dei menu scegliere Strumenti, Test proprietà progetto. Il valore $(VC_IncludePath);$(WindowsSDK_IncludePath);D:\Include;D:\Include; viene visualizzato in una finestra di dialogo.

Recupero e impostazione delle proprietà degli elementi di progetto di Visual C++

  1. Nel progetto TestVCProjectProperties creato nella procedura precedente, passare al metodo MenuItemCallback. Aggiungere il codice seguente per trovare un file con estensione cpp nel progetto, ottenere la proprietà Directory di inclusione aggiuntive e impostarla su D:\Include, quindi visualizzare una finestra di dialogo che mostra il nuovo valore:

    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. Compilare la soluzione e avviare il debug. Aprire un progetto Visual C++ nell'istanza sperimentale. Nella barra dei menu scegliere Strumenti, Test proprietà progetto. Una finestra di dialogo mostra il valore $(VC_IncludePath);$(WindowsSDK_IncludePath);D:\Include;D:\Include; e una seconda finestra di dialogo mostra il valore D:\Include.

  3. Per esaminare la posizione in cui il valore persiste, salvare tutti i file nel progetto aperto nell'istanza sperimentale. Il nuovo valore viene visualizzato nel file .vcxproj.

Rilevamento delle modifiche ai valori delle proprietà

  1. È possibile sottoscrivere l'evento ItemPropertyChange2 per rilevare quando una proprietà di progetto o di elemento di progetto Visual C++ ottiene un valore diverso.

    Nella classe TestVCProjectPropertiesPackage creare un gestore eventi per questo evento. In questo caso, il gestore visualizza solo una finestra di dialogo che mostra la proprietà che è stata modificata.

    void OnVCProjectEngineItemPropertyChange(Object item, string strPropertySheet, string strItemType, string PropertyName)
    {
        MessageBox.Show("got property change event for " + PropertyName);
    }
    
  2. Nel metodo Initialize ottenere VCProjectEngineEventsObject dagli eventi dell'oggetto Application, quindi aggiungere il gestore eventi appena creato:

    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. Compilare la soluzione e avviare il debug. Aprire un progetto Visual C++ nell'istanza sperimentale. Nella barra dei menu scegliere Strumenti, Test proprietà progetto. In una finestra di dialogo viene visualizzato $(VC_IncludePath);$(WindowsSDK_IncludePath);D:\Include;D:\Include;, in una seconda finestra di dialogo viene visualizzato Got property change event for IncludePath, in una terza finestra di dialogo viene visualizzato D:\Include e in una quarta finestra di dialogo viene visualizzato Got property change event for AdditionalIncludeDirectories.

    Nota

    L'evento relativo alla modifica di proprietà non verrà generato dopo che le modifiche in questo codice saranno state rese persistenti.Per vedere l'evento, modificare il valore della proprietà impostandolo diversamente.