Share via


How to: Persist the Property of a Project Item

You may want to persist a property you add to a project item, such as the author of a source file. You can do this by storing the property in the project file.

The first step to persist a property in a project file is to obtain the hierarchy of the project as an IVsHierarchy interface. You can obtain this interface either by using Automation or by using IVsMonitorSelection. Once you obtain the interface, you can use it to determine which project item is currently selected. Once you have the project item ID, you can use SetItemAttribute to add the property.

In the following procedures, you persist the VsPkg.cs property Author with the value Tom in the project file.

To obtain the project hierarchy by using Automation

  • Add the following code to your VSPackage:

    Dim dte As EnvDTE.DTE = CType(Package.GetGlobalService(GetType(EnvDTE.DTE)), EnvDTE.DTE)
    Dim project As EnvDTE.Project = dte.Solution.Projects.Item(1)
    
    Dim uniqueName As String = project.UniqueName
    Dim solution As IVsSolution = CType(Package.GetGlobalService(GetType(SVsSolution)), IVsSolution)
    Dim hierarchy As IVsHierarchy
    solution.GetProjectOfUniqueName(uniqueName, hierarchy)
    
    EnvDTE.DTE dte = (EnvDTE.DTE)Package.GetGlobalService(typeof(EnvDTE.DTE));
    EnvDTE.Project project = dte.Solution.Projects.Item(1);
    
    string uniqueName = project.UniqueName;
    IVsSolution solution = (IVsSolution)Package.GetGlobalService(typeof(SVsSolution));
    IVsHierarchy hierarchy;
    solution.GetProjectOfUniqueName(uniqueName, out hierarchy);
    

To persist the project item property by using Automation

  • Add the following code to the code given in the method in the previous procedure:

    Dim buildPropertyStorage As IVsBuildPropertyStorage = CType(hierarchy, IVsBuildPropertyStorage)
    If Not buildPropertyStorage Is Nothing Then
        Dim itemId As UInteger
        Dim fullPath As String = CType(project.ProjectItems.Item("VsPkg.vb").Properties.Item("FullPath").Value, String)
        hierarchy.ParseCanonicalName(fullPath, itemId)
        buildPropertyStorage.SetItemAttribute(itemId, "Author", "Tom")
    End If
    
    IVsBuildPropertyStorage buildPropertyStorage =
        hierarchy as IVsBuildPropertyStorage;
    if (buildPropertyStorage != null)
    {
        uint itemId;
        string fullPath = 
            (string)project.ProjectItems.Item("VsPkg.cs").Properties.Item("FullPath").Value;
        hierarchy.ParseCanonicalName(fullPath, out itemId);
        buildPropertyStorage.SetItemAttribute(itemId, "Author", "Tom");
    }
    

To obtain the project hierarchy by using IVsMonitorSelection

  1. Add the following code to your VSPackage:

    Dim hierarchy As IVsHierarchy = Nothing
    Dim hierarchyPtr As IntPtr = IntPtr.Zero
    Dim selectionContainer As IntPtr = IntPtr.Zero
    Dim itemId As UInteger
    
    ' Retrieve shell interface in order to get current selection
    Dim monitorSelection As IVsMonitorSelection = CType(Package.GetGlobalService(GetType(SVsShellMonitorSelection)), IVsMonitorSelection)
    If monitorSelection Is Nothing Then
        Throw New InvalidOperationException
    End If
    
    Try
        ' Get the current project hierarchy, project item, and selection container for the current selection
        ' If the selection spans multiple hierarchies, hierarchyPtr is Zero
        Dim multiItemSelect As IVsMultiItemSelect = Nothing
        ErrorHandler.ThrowOnFailure(monitorSelection.GetCurrentSelection(
                                    hierarchyPtr, itemId, multiItemSelect, selectionContainer))
    
        ' We only care if there is only one node selected in the tree
        If Not (itemId = VSConstants.VSITEMID.Nil _
                Or hierarchyPtr = IntPtr.Zero _
                Or (Not multiItemSelect Is Nothing) _
                Or itemId = VSConstants.VSITEMID.Selection) Then
            hierarchy = CType(Marshal.GetObjectForIUnknown(hierarchyPtr), IVsHierarchy)
        End If
    Finally
        If hierarchyPtr <> IntPtr.Zero Then
            Marshal.Release(hierarchyPtr)
        End If
        If selectionContainer <> IntPtr.Zero Then
            Marshal.Release(selectionContainer)
        End If
    End Try
    
    IVsHierarchy hierarchy = null;
    IntPtr hierarchyPtr = IntPtr.Zero;
    IntPtr selectionContainer = IntPtr.Zero;
    uint itemid;
    
    // Retrieve shell interface in order to get current selection
    IVsMonitorSelection monitorSelection = Package.GetGlobalService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection;
    if (monitorSelection == null)
        throw new InvalidOperationException();
    
    try
    {
        // Get the current project hierarchy, project item, and selection container for the current selection
        // If the selection spans multiple hierachies, hierarchyPtr is Zero
        IVsMultiItemSelect multiItemSelect = null;
        ErrorHandler.ThrowOnFailure(
            monitorSelection.GetCurrentSelection(
                out hierarchyPtr, out itemid,
                out multiItemSelect, out selectionContainer));
    
        // We only care if there is only one node selected in the tree
        if (!(itemid == VSConstants.VSITEMID_NIL ||
            hierarchyPtr == IntPtr.Zero ||
            multiItemSelect != null ||
            itemid == VSConstants.VSITEMID_SELECTION))
        {
            hierarchy = Marshal.GetObjectForIUnknown(hierarchyPtr)
                as IVsHierarchy;
        }
    }
    finally
    {
        if (hierarchyPtr != IntPtr.Zero)
            Marshal.Release(hierarchyPtr);
        if (selectionContainer != IntPtr.Zero)
            Marshal.Release(selectionContainer);
    }
    

To persist the selected project item property, given the project hierarchy

  • Add the following code to the code given in the method in the previous procedure:

    Dim buildPropertyStorage As IVsBuildPropertyStorage = CType(hierarchy, IVsBuildPropertyStorage)
    If Not buildPropertyStorage Is Nothing Then
        buildPropertyStorage.SetItemAttribute(itemId, "Author", "Tom")
    End If
    
    IVsBuildPropertyStorage buildPropertyStorage =
        hierarchy as IVsBuildPropertyStorage;
    if (buildPropertyStorage != null)
    {
        buildPropertyStorage.SetItemAttribute(itemid, "Author", "Tom");
    }
    

To verify that the property is persisted

  1. Start Visual Studio and then open or create a solution.

  2. Select the project item VsPkg.cs in Solution Explorer.

  3. Use a breakpoint or otherwise determine that your VSPackage is loaded and that SetItemAttribute runs.

    Note

    You can autoload a VSPackage in the UI context UICONTEXT_SolutionExists. For more information, see How to: Autoload a VSPackage.

  4. Close Visual Studio and then open the project file in Notepad. You should see the <Author> tag with the value Tom, as follows:

    <Compile Include="VsPkg.cs">
        <Author>Tom</Author>
    </Compile>
    

See Also

Other Resources

Project Items (Visual Studio SDK)