如何:保存项目项的属性

您可能希望保留已添加到项目项的属性,例如源文件的作者。 通过存储属性执行此操作项目文件。

保留的第一步属性在项目文件中获取项目的层次结构作为 IVsHierarchy 接口。 使用 IVsMonitorSelection,可以获取此接口使用自动化或。 一旦获取接口,可以使用它确定哪个项目项当前被选定。 只要有项目项 ID,可以使用 SetItemAttribute 添加属性。

在下面的过程中,将保留在项目文件与该值 tom 的 VsPkg.cs 属性 作者 。

使用自动化,获取项目层次结构

  • 将以下代码添加到 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);
    

使用自动化,保留项目项属性

  • 将以下代码添加到前面过程中的方法提供的代码:

    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");
    }
    

使用 IVsMonitorSelection,获取项目层次结构

  1. 将以下代码添加到 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);
    }
    

保存选定的项目项属性命名项目层次结构

  • 将以下代码添加到前面过程中的方法提供的代码:

    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");
    }
    

验证属性是否仍存在

  1. 开始 Visual Studio 然后打开或创建解决方案。

  2. 选择在 解决方案资源管理器的项目项 VsPkg.cs。

  3. 使用断点或确定 VSPackage 加载,并且 SetItemAttribute 运行。

    备注

    您在 UI 上下文 UICONTEXT_SolutionExists自动上载 VSPackage。有关更多信息,请参见 如何:自动上载 VSPackage

  4. 关闭 " Visual Studio 然后打开在记事本的项目文件。 您应看到与 Author 该值 tom 的标记,如下所示:

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

请参见

其他资源

项目项 (Visual Studio SDK)