Freigeben über


Verwalten von Universellen Windows-Projekten

Universelle Windows-Apps sind Apps, die sowohl auf Windows 8.1 als auch auf Windows Telefon 8.1 abzielen, sodass Entwickler Code und andere Ressourcen auf beiden Plattformen verwenden können. Der freigegebene Code und die freigegebenen Ressourcen werden in einem freigegebenen Projekt gespeichert, während der plattformspezifische Code und ressourcen in separaten Projekten, einer für Windows und die andere für Windows Telefon gespeichert werden. Weitere Informationen zu universellen Windows-Apps finden Sie unter Universelle Windows-Apps. Visual Studio-Erweiterungen, die Projekte verwalten, sollten beachten, dass universelle Windows-App-Projekte eine Struktur aufweisen, die sich von Einzelplattform-Apps unterscheidet. In dieser exemplarischen Vorgehensweise wird gezeigt, wie Sie im freigegebenen Projekt navigieren und die freigegebenen Elemente verwalten.

  1. Erstellen Sie ein C#VSIX-Projekt namens TestUniversalProject. (File>New>Project and then C#>Extensibility>Visual Studio Package). Fügen Sie eine Projektelementvorlage für benutzerdefinierte Befehle hinzu (klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektknoten, und wählen Sie "Neues Element hinzufügen>" aus, und wechseln Sie dann zur Erweiterbarkeit. Nennen Sie die Datei TestUniversalProject.

  2. Fügen Sie einen Verweis auf Microsoft.VisualStudio.Shell.Interop.12.1.DesignTime.dll und Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime.dll (im Abschnitt "Erweiterungen") hinzu.

  3. Öffnen Sie TestUniversalProject.cs , und fügen Sie die folgenden using Direktiven hinzu:

    using EnvDTE;
    using EnvDTE80;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.PlatformUI;
    using Microsoft.Internal.VisualStudio.PlatformUI;
    using System.Collections.Generic;
    using System.IO;
    using System.Windows.Forms;
    
  4. Fügen Sie in der TestUniversalProject Klasse ein privates Feld hinzu, das auf das Ausgabefenster zeigt.

    public sealed class TestUniversalProject
    {
        IVsOutputWindowPane output;
    . . .
    }
    
  5. Legen Sie den Verweis auf den Ausgabebereich im TestUniversalProject-Konstruktor fest:

    private TestUniversalProject(Package package)
    {
        if (package == null)
        {
            throw new ArgumentNullException("package");
        }
    
        this.package = package;
    
        OleMenuCommandService commandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
        if (commandService != null)
        {
            CommandID menuCommandID = new CommandID(MenuGroup, CommandId);
            EventHandler eventHandler = this.ShowMessageBox;
            MenuCommand menuItem = new MenuCommand(eventHandler, menuCommandID);
            commandService.AddCommand(menuItem);
        }
    
        // get a reference to the Output window
        output = (IVsOutputWindowPane)ServiceProvider.GetService(typeof(SVsGeneralOutputWindowPane));
    }
    
  6. Entfernen Sie den vorhandenen Code aus der ShowMessageBox Methode:

    private void ShowMessageBox(object sender, EventArgs e)
    {
    }
    
  7. Rufen Sie das DTE-Objekt ab, das in dieser exemplarischen Vorgehensweise für verschiedene Zwecke verwendet wird. Stellen Sie außerdem sicher, dass eine Lösung geladen wird, wenn auf die Menüschaltfläche geklickt wird.

    private void ShowMessageBox(object sender, EventArgs e)
    {
        var dte = (EnvDTE.DTE)this.ServiceProvider.GetService(typeof(EnvDTE.DTE));
        if (dte.Solution != null)
        {
            . . .
        }
        else
        {
            MessageBox.Show("No solution is open");
            return;
        }
    }
    
  8. Suchen Sie das freigegebene Projekt. Das freigegebene Projekt ist ein reiner Container; es erstellt keine Ausgaben oder erzeugt sie. Die folgende Methode findet das erste freigegebene Projekt in der Projektmappe, indem nach dem IVsHierarchy Objekt gesucht wird, das über die freigegebene Projektfunktion verfügt.

    private IVsHierarchy FindSharedProject()
    {
        var sln = (IVsSolution)this.ServiceProvider.GetService(typeof(SVsSolution));
        Guid empty = Guid.Empty;
        IEnumHierarchies enumHiers;
    
        //get all the projects in the solution
        ErrorHandler.ThrowOnFailure(sln.GetProjectEnum((uint)__VSENUMPROJFLAGS.EPF_LOADEDINSOLUTION, ref empty, out enumHiers));
        foreach (IVsHierarchy hier in ComUtilities.EnumerableFrom(enumHiers))
        {
            if (PackageUtilities.IsCapabilityMatch(hier, "SharedAssetsProject"))
            {
                return hier;
            }
        }
        return null;
    }
    
  9. Geben Sie in der ShowMessageBox Methode die Untertitel (den Projektnamen, der im Projektmappen-Explorer) des freigegebenen Projekts angezeigt wird.

    private void ShowMessageBox(object sender, EventArgs e)
    {
        var dte = (DTE)this.ServiceProvider.GetService(typeof(DTE));
    
        if (dte.Solution != null)
        {
            var sharedHier = this.FindSharedProject();
            if (sharedHier != null)
            {
                string sharedCaption = HierarchyUtilities.GetHierarchyProperty<string>(sharedHier, (uint)VSConstants.VSITEMID.Root,
                     (int)__VSHPROPID.VSHPROPID_Caption);
                output.OutputStringThreadSafe(string.Format("Found shared project: {0}\n", sharedCaption));
            }
            else
            {
                MessageBox.Show("Solution has no shared project");
                return;
            }
        }
        else
        {
            MessageBox.Show("No solution is open");
            return;
        }
    }
    
  10. Rufen Sie das aktive Plattformprojekt ab. Plattformprojekte sind die Projekte, die plattformspezifischen Code und Ressourcen enthalten. Die folgende Methode verwendet das neue Feld VSHPROPID_SharedItemContextHierarchy , um das aktive Plattformprojekt abzurufen.

    private IVsHierarchy GetActiveProjectContext(IVsHierarchy hierarchy)
    {
        IVsHierarchy activeProjectContext;
        if (HierarchyUtilities.TryGetHierarchyProperty(hierarchy, (uint)VSConstants.VSITEMID.Root,
             (int)__VSHPROPID7.VSHPROPID_SharedItemContextHierarchy, out activeProjectContext))
        {
            return activeProjectContext;
        }
        else
        {
            return null;
        }
    }
    
  11. Geben Sie in der ShowMessageBox Methode die Untertitel des aktiven Plattformprojekts aus.

    private void ShowMessageBox(object sender, EventArgs e)
    {
        var dte = (DTE)this.ServiceProvider.GetService(typeof(DTE));
    
        if (dte.Solution != null)
        {
            var sharedHier = this.FindSharedProject();
            if (sharedHier != null)
            {
                string sharedCaption = HierarchyUtilities.GetHierarchyProperty<string>(sharedHier, (uint)VSConstants.VSITEMID.Root,
                     (int)__VSHPROPID.VSHPROPID_Caption);
                output.OutputStringThreadSafe(string.Format("Shared project: {0}\n", sharedCaption));
    
                var activePlatformHier = this.GetActiveProjectContext(sharedHier);
                if (activePlatformHier != null)
                {
                    string activeCaption = HierarchyUtilities.GetHierarchyProperty<string>(activePlatformHier,
                         (uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_Caption);
                    output.OutputStringThreadSafe(string.Format("Active platform project: {0}\n", activeCaption));
                }
                else
                {
                    MessageBox.Show("Shared project has no active platform project");
                }
            }
            else
            {
                MessageBox.Show("Solution has no shared project");
            }
        }
        else
        {
            MessageBox.Show("No solution is open");
        }
    }
    
  12. Durchlaufen Sie die Plattformprojekte. Mit der folgenden Methode werden alle importierten (Plattform)-Projekte aus dem freigegebenen Projekt abgerufen.

    private IEnumerable<IVsHierarchy> EnumImportingProjects(IVsHierarchy hierarchy)
    {
        IVsSharedAssetsProject sharedAssetsProject;
        if (HierarchyUtilities.TryGetHierarchyProperty(hierarchy, (uint)VSConstants.VSITEMID.Root,
            (int)__VSHPROPID7.VSHPROPID_SharedAssetsProject, out sharedAssetsProject)
            && sharedAssetsProject != null)
        {
            foreach (IVsHierarchy importingProject in sharedAssetsProject.EnumImportingProjects())
            {
                yield return importingProject;
            }
        }
    }
    

    Wichtig

    Wenn der Benutzer ein universelles C++-Windows-App-Projekt in der experimentellen Instanz geöffnet hat, löst der obige Code eine Ausnahme aus. Dies ist ein bekanntes Problem. Um die Ausnahme zu vermeiden, ersetzen Sie den foreach obigen Block durch Folgendes:

    var importingProjects = sharedAssetsProject.EnumImportingProjects();
    for (int i = 0; i < importingProjects.Count; ++i)
    {
        yield return importingProjects[i];
    }
    
  13. Geben Sie in der ShowMessageBox Methode die Untertitel jedes Plattformprojekts aus. Fügen Sie den folgenden Code nach der Zeile ein, die die Untertitel des aktiven Plattformprojekts ausgibt. Nur die geladenen Plattformprojekte werden in dieser Liste angezeigt.

    output.OutputStringThreadSafe("Platform projects:\n");
    
    IEnumerable<IVsHierarchy> projects = this.EnumImportingProjects(sharedHier);
    
    bool isActiveProjectSet = false;
    foreach (IVsHierarchy platformHier in projects)
    {
        string platformCaption = HierarchyUtilities.GetHierarchyProperty<string>(platformHier, (uint)VSConstants.VSITEMID.Root,
            (int)__VSHPROPID.VSHPROPID_Caption);
        output.OutputStringThreadSafe(string.Format(" * {0}\n", platformCaption));
    }
    
  14. Ändern Sie das aktive Plattformprojekt. Mit der folgenden Methode wird das aktive Projekt mithilfe von SetProperty.

    private int SetActiveProjectContext(IVsHierarchy hierarchy, IVsHierarchy activeProjectContext)
    {
        return hierarchy.SetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID7.VSHPROPID_SharedItemContextHierarchy, activeProjectContext);
    }
    
  15. Ändern Sie in der ShowMessageBox Methode das aktive Plattformprojekt. Fügen Sie diesen Code in den foreach Block ein.

    bool isActiveProjectSet = false;
    string platformCaption = null;
    foreach (IVsHierarchy platformHier in projects)
    {
        platformCaption = HierarchyUtilities.GetHierarchyProperty<string>(platformHier, (uint)VSConstants.VSITEMID.Root,
             (int)__VSHPROPID.VSHPROPID_Caption);
        output.OutputStringThreadSafe(string.Format(" * {0}\n", platformCaption));
    
        // if this project is neither the shared project nor the current active platform project,
        // set it to be the active project
        if (!isActiveProjectSet && platformHier != activePlatformHier)
        {
            this.SetActiveProjectContext(sharedHier, platformHier);
            activePlatformHier = platformHier;
            isActiveProjectSet = true;
        }
    }
    output.OutputStringThreadSafe("set active project: " + platformCaption +'\n');
    
  16. Probieren Sie es jetzt aus. Drücken Sie F5, um die experimentelle Instanz zu starten. Erstellen Sie ein C#-Projekt für universelle Hub-Apps in der experimentellen Instanz (im Dialogfeld "Neues Projekt", Visual C#>Windows>8>Universal>Hub-App). Wechseln Sie nach dem Laden der Lösung zum Menü "Extras ", und klicken Sie auf "TestUniversalProject aufrufen", und überprüfen Sie dann den Text im Ausgabebereich . Folgendes sollte angezeigt werden:

    Found shared project: HubApp.Shared
    The active platform project: HubApp.Windows
    Platform projects:
     * HubApp.Windows
     * HubApp.WindowsPhone
    set active project: HubApp.WindowsPhone
    

Verwalten der freigegebenen Elemente im Plattformprojekt

  1. Suchen Sie die freigegebenen Elemente im Plattformprojekt. Die Elemente im freigegebenen Projekt werden im Plattformprojekt als freigegebene Elemente angezeigt. Sie können sie nicht im Projektmappen-Explorer sehen, aber Sie können die Projekthierarchie durchlaufen, um sie zu finden. Die folgende Methode führt die Hierarchie durch und sammelt alle freigegebenen Elemente. Sie gibt optional die Untertitel jedes Elements aus. Die freigegebenen Elemente werden durch die neue Eigenschaft VSHPROPID_IsSharedItemidentifiziert.

    private void InspectHierarchyItems(IVsHierarchy hier, uint itemid, int level, List<uint> itemIds, bool getSharedItems, bool printItems)
    {
        string caption = HierarchyUtilities.GetHierarchyProperty<string>(hier, itemid, (int)__VSHPROPID.VSHPROPID_Caption);
        if (printItems)
            output.OutputStringThreadSafe(string.Format("{0}{1}\n", new string('\t', level), caption));
    
        // if getSharedItems is true, inspect only shared items; if it's false, inspect only unshared items
        bool isSharedItem;
        if (HierarchyUtilities.TryGetHierarchyProperty(hier, itemid, (int)__VSHPROPID7.VSHPROPID_IsSharedItem, out isSharedItem)
            && (isSharedItem == getSharedItems))
        {
            itemIds.Add(itemid);
        }
    
        uint child;
        if (HierarchyUtilities.TryGetHierarchyProperty(hier, itemid, (int)__VSHPROPID.VSHPROPID_FirstChild, Unbox.AsUInt32, out child)
            && child != (uint)VSConstants.VSITEMID.Nil)
        {
            this.InspectHierarchyItems(hier, child, level + 1, itemIds, isSharedItem, printItems);
    
            while (HierarchyUtilities.TryGetHierarchyProperty(hier, child, (int)__VSHPROPID.VSHPROPID_NextSibling, Unbox.AsUInt32, out child)
                && child != (uint)VSConstants.VSITEMID.Nil)
            {
                this.InspectHierarchyItems(hier, child, level + 1, itemIds, isSharedItem, printItems);
            }
        }
    }
    
  2. Fügen Sie in der ShowMessageBox Methode den folgenden Code hinzu, um die Elemente der Plattformprojekthierarchie zu durchlaufen. Fügen Sie ihn in den foreach Block ein.

    output.OutputStringThreadSafe("Walk the active platform project:\n");
    var sharedItemIds = new List<uint>();
    this.InspectHierarchyItems(activePlatformHier, (uint)VSConstants.VSITEMID.Root, 1, sharedItemIds, true, true);
    
  3. Lesen Sie die freigegebenen Elemente. Die freigegebenen Elemente werden im Plattformprojekt als ausgeblendete verknüpfte Dateien angezeigt, und Sie können alle Eigenschaften als normale verknüpfte Dateien lesen. Der folgende Code liest den vollständigen Pfad des ersten freigegebenen Elements.

    var sharedItemId = sharedItemIds[0];
    string fullPath;
    ErrorHandler.ThrowOnFailure(((IVsProject)activePlatformHier).GetMkDocument(sharedItemId, out fullPath));
    output.OutputStringThreadSafe(string.Format("Shared item full path: {0}\n", fullPath));
    
  4. Probieren Sie es jetzt aus. Drücken Sie F5 , um die experimentelle Instanz zu starten. Erstellen Sie ein C#-Projekt für universelle Hub-Apps in der experimentellen Instanz (im Dialogfeld "Neues Projekt", Visual C#>Windows>8>Universal>Hub App), wechseln Sie zum Menü "Extras", und klicken Sie auf "TestUniversalProject aufrufen", und überprüfen Sie dann den Text im Ausgabebereich. Folgendes sollte angezeigt werden:

    Found shared project: HubApp.Shared
    The active platform project: HubApp.Windows
    Platform projects:
     * HubApp.Windows
     * HubApp.WindowsPhone
    set active project: HubApp.WindowsPhone
    Walk the active platform project:
        HubApp.WindowsPhone
            <HubApp.Shared>
                App.xaml
                    App.xaml.cs
                Assets
                    DarkGray.png
                    LightGray.png
                    MediumGray.png
                Common
                    NavigationHelper.cs
                    ObservableDictionary.cs
                    RelayCommand.cs
                    SuspensionManager.cs
                DataModel
                    SampleData.json
                    SampleDataSource.cs
                HubApp.Shared.projitems
                Strings
                    en-US
                        Resources.resw
            Assets
                HubBackground.theme-dark.png
                HubBackground.theme-light.png
                Logo.scale-240.png
                SmallLogo.scale-240.png
                SplashScreen.scale-240.png
                Square71x71Logo.scale-240.png
                StoreLogo.scale-240.png
                WideLogo.scale-240.png
            HubPage.xaml
                HubPage.xaml.cs
            ItemPage.xaml
                ItemPage.xaml.cs
            Package.appxmanifest
            Properties
                AssemblyInfo.cs
            References
                .NET for Windows Store apps
                HubApp.Shared
                Windows Phone 8.1
            SectionPage.xaml
                SectionPage.xaml.cs
    

Erkennen von Änderungen in Plattformprojekten und freigegebenen Projekten

  1. Sie können Hierarchie- und Projektereignisse verwenden, um Änderungen in freigegebenen Projekten zu erkennen, genau wie für Plattformprojekte. Die Projektelemente im freigegebenen Projekt sind jedoch nicht sichtbar, was bedeutet, dass bestimmte Ereignisse nicht ausgelöst werden, wenn freigegebene Projektelemente geändert werden.

    Berücksichtigen Sie die Abfolge von Ereignissen, wenn eine Datei in einem Projekt umbenannt wird:

    1. Der Dateiname wird auf dem Datenträger geändert.

    2. Die Projektdatei wird aktualisiert, um den neuen Namen der Datei einzuschließen.

      Hierarchieereignisse (z. BIVsHierarchyEvents. ) verfolgen die änderungen, die in der Benutzeroberfläche angezeigt werden, wie in der Projektmappen-Explorer. Hierarchieereignisse betrachten einen Dateibenennungsvorgang, der aus einem Dateilöschvorgang und dann einer Dateizugabe besteht. Wenn jedoch unsichtbare Elemente geändert werden, löst das Hierarchieereignissystem ein OnItemDeleted Ereignis, aber kein OnItemAdded Ereignis aus. Wenn Sie also eine Datei in ein Plattformprojekt umbenennen, erhalten Sie beide OnItemDeleted und OnItemAdded, aber wenn Sie eine Datei in einem freigegebenen Projekt umbenennen, erhalten Sie nur OnItemDeleted.

      Zum Nachverfolgen von Änderungen in Projektelementen können Sie DTE-Projektelementereignisse (die in ProjectItemsEventsClass) behandeln. Wenn Sie jedoch eine große Anzahl von Ereignissen behandeln, können Sie eine bessere Leistungsbehandlung für die Ereignisse erzielen.IVsTrackProjectDocuments2 In dieser exemplarischen Vorgehensweise zeigen wir nur die Hierarchieereignisse und die DTE-Ereignisse an. In diesem Verfahren fügen Sie einem freigegebenen Projekt und einem Plattformprojekt einen Ereignislistener hinzu. Wenn Sie dann eine Datei in einem freigegebenen Projekt und eine andere Datei in einem Plattformprojekt umbenennen, können Sie die Ereignisse sehen, die für jeden Umbenennungsvorgang ausgelöst werden.

      In diesem Verfahren fügen Sie einem freigegebenen Projekt und einem Plattformprojekt einen Ereignislistener hinzu. Wenn Sie dann eine Datei in einem freigegebenen Projekt und eine andere Datei in einem Plattformprojekt umbenennen, können Sie die Ereignisse sehen, die für jeden Umbenennungsvorgang ausgelöst werden.

  2. Fügen Sie einen Ereignislistener hinzu. Fügen Sie dem Projekt eine neue Klassendatei hinzu, und rufen Sie sie "HierarchyEventListener.cs" auf.

  3. Öffnen Sie die Datei "HierarchyEventListener.cs ", und fügen Sie die folgenden Direktiven hinzu:

    using Microsoft.VisualStudio.Shell.Interop;
    using Microsoft.VisualStudio;
    using System.IO;
    
  4. Implementieren Sie die HierarchyEventListener Klasse IVsHierarchyEvents:

    class HierarchyEventListener : IVsHierarchyEvents
    { }
    
  5. Implementieren Sie die Member von IVsHierarchyEvents, wie im folgenden Code beschrieben.

    class HierarchyEventListener : IVsHierarchyEvents
    {
        private IVsHierarchy hierarchy;
        IVsOutputWindowPane output;
    
        internal HierarchyEventListener(IVsHierarchy hierarchy, IVsOutputWindowPane outputWindow) {
             this.hierarchy = hierarchy;
             this.output = outputWindow;
        }
    
        int IVsHierarchyEvents.OnInvalidateIcon(IntPtr hIcon) {
            return VSConstants.S_OK;
        }
    
        int IVsHierarchyEvents.OnInvalidateItems(uint itemIDParent) {
            return VSConstants.S_OK;
        }
    
        int IVsHierarchyEvents.OnItemAdded(uint itemIDParent, uint itemIDSiblingPrev, uint itemIDAdded) {
            output.OutputStringThreadSafe("IVsHierarchyEvents.OnItemAdded: " + itemIDAdded + "\n");
            return VSConstants.S_OK;
        }
    
        int IVsHierarchyEvents.OnItemDeleted(uint itemID) {
            output.OutputStringThreadSafe("IVsHierarchyEvents.OnItemDeleted: " + itemID + "\n");
            return VSConstants.S_OK;
        }
    
        int IVsHierarchyEvents.OnItemsAppended(uint itemIDParent) {
            output.OutputStringThreadSafe("IVsHierarchyEvents.OnItemsAppended\n");
            return VSConstants.S_OK;
        }
    
        int IVsHierarchyEvents.OnPropertyChanged(uint itemID, int propID, uint flags) {
            output.OutputStringThreadSafe("IVsHierarchyEvents.OnPropertyChanged: item ID " + itemID + "\n");
            return VSConstants.S_OK;
        }
    }
    
  6. Fügen Sie in derselben Klasse einen weiteren Ereignishandler für das DTE-Ereignis ItemRenamedhinzu, das immer dann auftritt, wenn ein Projektelement umbenannt wird.

    public void OnItemRenamed(EnvDTE.ProjectItem projItem, string oldName)
    {
        output.OutputStringThreadSafe(string.Format("[Event] Renamed {0} to {1} in project {2}\n",
             oldName, Path.GetFileName(projItem.get_FileNames(1)), projItem.ContainingProject.Name));
    }
    
  7. Registrieren Sie sich für die Hierarchieereignisse. Sie müssen sich für jedes Projekt, das Sie nachverfolgen, separat registrieren. Fügen Sie den folgenden Code in ShowMessageBox, eine für das freigegebene Projekt und die andere für eines der Plattformprojekte hinzu.

    // hook up the event listener for hierarchy events on the shared project
    HierarchyEventListener listener1 = new HierarchyEventListener(sharedHier, output);
    uint cookie1;
    sharedHier.AdviseHierarchyEvents(listener1, out cookie1);
    
    // hook up the event listener for hierarchy events on the
    active project
    HierarchyEventListener listener2 = new HierarchyEventListener(activePlatformHier, output);
    uint cookie2;
    activePlatformHier.AdviseHierarchyEvents(listener2, out cookie2);
    
  8. Registrieren Sie sich für das DTE-Projektelementereignis ItemRenamed. Fügen Sie den folgenden Code hinzu, nachdem Sie den zweiten Listener eingebunden haben.

    // hook up DTE events for project items
    Events2 dteEvents = (Events2)dte.Events;
    dteEvents.ProjectItemsEvents.ItemRenamed += listener1.OnItemRenamed;
    
  9. Ändern Sie das freigegebene Element. Sie können freigegebene Elemente in einem Plattformprojekt nicht ändern; Stattdessen müssen Sie sie im freigegebenen Projekt ändern, bei dem es sich um den tatsächlichen Besitzer dieser Elemente handelt. Sie können die entsprechende Element-ID im freigegebenen Projekt IsDocumentInProjectabrufen, sodass sie den vollständigen Pfad des freigegebenen Elements erhält. Anschließend können Sie das freigegebene Element ändern. Die Änderung wird an die Plattformprojekte weitergegeben.

    Wichtig

    Sie sollten herausfinden, ob ein Projektelement ein freigegebenes Element ist, bevor Sie es ändern.

    Mit der folgenden Methode wird der Name einer Projektelementdatei geändert.

    private void ModifyFileNameInProject(IVsHierarchy project, string path)
    {
        int found;
        uint projectItemID;
        VSDOCUMENTPRIORITY[] priority = new VSDOCUMENTPRIORITY[1];
        if (ErrorHandler.Succeeded(((IVsProject)project).IsDocumentInProject(path, out found, priority, out projectItemID))
            && found != 0)
        {
            var name = DateTime.Now.Ticks.ToString() + Path.GetExtension(path);
            project.SetProperty(projectItemID, (int)__VSHPROPID.VSHPROPID_EditLabel, name);
            output.OutputStringThreadSafe(string.Format("Renamed {0} to {1}\n", path,name));
        }
    }
    
  10. Rufen Sie diese Methode nach dem anderen Code auf ShowMessageBox , um den Dateinamen des Elements im freigegebenen Projekt zu ändern. Fügen Sie dies nach dem Code ein, der den vollständigen Pfad des Elements im freigegebenen Projekt abruft.

    // change the file name of an item in a shared project
    this.InspectHierarchyItems(activePlatformHier, (uint)VSConstants.VSITEMID.Root, 1, sharedItemIds, true, true);
    ErrorHandler.ThrowOnFailure(((IVsProject)activePlatformHier).GetMkDocument(sharedItemId, out fullPath));
    output.OutputStringThreadSafe(string.Format("Shared project item ID = {0}, full path = {1}\n", sharedItemId, fullPath));
    this.ModifyFileNameInProject(sharedHier, fullPath);
    
  11. Erstellen Sie das Projekt, und führen Sie es aus. Erstellen Sie eine universelle C#-Hub-App in der experimentellen Instanz, wechseln Sie zum Menü "Extras ", und klicken Sie auf "TestUniversalProject aufrufen", und überprüfen Sie den Text im allgemeinen Ausgabebereich. Der Name des ersten Elements im freigegebenen Projekt (wir erwarten, dass es sich um die Datei "App.xaml " handeln soll) sollte geändert werden, und Sie sollten sehen, dass das ItemRenamed Ereignis ausgelöst wurde. Da das Umbenennen von "App.xaml" dazu führt, dass "App.xaml.cs" ebenfalls umbenannt wird, sollten vier Ereignisse (zwei für jedes Plattformprojekt) angezeigt werden. (DTE-Ereignisse verfolgen die Elemente im freigegebenen Projekt nicht.) Es sollten zwei OnItemDeleted Ereignisse (eines für jedes Plattformprojekt) angezeigt werden, aber keine OnItemAdded Ereignisse.

  12. Versuchen Sie nun, eine Datei in einem Plattformprojekt umzubenennen, und Sie können den Unterschied in den Ereignissen sehen, die ausgelöst werden. Fügen Sie den folgenden Code nach ShowMessageBox dem Aufruf von ModifyFileName.

    // change the file name of an item in a platform project
    var unsharedItemIds = new List<uint>();
    this.InspectHierarchyItems(activePlatformHier, (uint)VSConstants.VSITEMID.Root, 1, unsharedItemIds, false, false);
    
    var unsharedItemId = unsharedItemIds[0];
    string unsharedPath;
    ErrorHandler.ThrowOnFailure(((IVsProject)activePlatformHier).GetMkDocument(unsharedItemId, out unsharedPath));
    output.OutputStringThreadSafe(string.Format("Platform project item ID = {0}, full path = {1}\n", unsharedItemId, unsharedPath));
    
    this.ModifyFileNameInProject(activePlatformHier, unsharedPath);
    
  13. Erstellen Sie das Projekt, und führen Sie es aus. Erstellen Sie ein universelles C#-Projekt in der experimentellen Instanz, wechseln Sie zum Menü "Extras ", und klicken Sie auf "TestUniversalProject aufrufen", und überprüfen Sie den Text im allgemeinen Ausgabebereich. Nachdem die Datei im Plattformprojekt umbenannt wurde, sollte sowohl ein Ereignis als auch ein OnItemAdded OnItemDeleted Ereignis angezeigt werden. Da das Ändern der Datei dazu führte, dass keine anderen Dateien geändert wurden, und da Änderungen an Elementen in einem Plattformprojekt nicht überall verteilt werden, gibt es nur eines dieser Ereignisse.