Wykonywanie zapytań względem interfejsu API projektu
Interfejs API zapytań projektu VisualStudio.Extensibility umożliwia wykonywanie zapytań dotyczących informacji z systemu projektu. Systemy projektów są częścią składników programu Visual Studio, które ułatwiają użytkownikom pracę z projektami i konserwowanie ich, uruchamianie kompilacji w celu generowania wyników i testowania danych wyjściowych.
Celem interfejsu API zapytań projektu jest:
- Praca z systemami projektów
- Pobieranie danych z projektów
- Wprowadzanie zmian w projektach
Niektóre przykłady obejmują opis plików zawartych w projekcie, pakiety NuGet, do których odwołuje się projekt, dodawanie nowych plików do projektu lub zmienianie właściwości projektu.
Więcej informacji na temat systemów projektów można znaleźć tutaj. Znajdź dokumentację koncepcyjną dotyczącą tego, czym jest system projektu, użycie i jego różne terminy tutaj.
Praca z interfejsem API zapytań projektu
To omówienie obejmuje najważniejsze scenariusze pracy z interfejsem API zapytań projektu:
- Uzyskiwanie dostępu do obszaru zapytania projektu
- Wykonywanie zapytań dotyczących systemu projektu dla projektu
- Określanie parametrów projektu, które mają zostać uwzględnione w wyniku zapytania
- Filtrowanie wyniku zapytania
- Użyj zagnieżdżonych zapytań, aby określić żądane właściwości
- Pobieranie kolekcji podrzędnej przy użyciu metody Get
- Wykonywanie zapytań o dodatkowe informacje z wcześniej zwróconego elementu
- Modyfikowanie projektu
- Zapytanie o właściwości projektu
- Wykonywanie zapytań o rozwiązania
- Wykonywanie zapytań dotyczących folderów rozwiązań
- Wyliczanie plików źródłowych z dodatkowymi informacjami w projekcie
- Wykonywanie zapytań dotyczących projektów, które są właścicielem określonego pliku źródłowego
- Wykonywanie zapytań o konfiguracje projektu i ich właściwości
- Wykonywanie zapytań dotyczących odwołań do projektu
- Zapytanie dotyczące odwołań do pakietu
- Wykonywanie zapytań dotyczących grup danych wyjściowych projektu
- Zapytanie dotyczące projektów startowych
- Zapytanie o konfiguracje rozwiązań
- Zapytanie akcji w celu załadowania/zwolnienia projektu
- Zapytanie akcji do tworzenia rozwiązań/projektów
- Zapytanie akcji w celu zapisania rozwiązania/projektu
- Zapytanie akcji w celu śledzenia zmian kwerendy
- Zapytanie akcji do pominięcia
Uzyskiwanie dostępu do obszaru zapytania projektu
Przed wykonaniem zapytania względem systemu projektu należy uzyskać wystąpienie obiektu obszaru zapytań projektu, które ma kilka metod asynchronicznych, które wysyłają zapytania lub aktualizują system projektu. Termin obszar zapytania projektu i termin obszar roboczy oznaczają to samo, obiekt, który zapewnia dostęp do wszystkich danych projektu.
Dostęp do obszaru zapytań projektu w rozszerzeniu poza procesem
Jeśli tworzysz rozszerzenie poza procesem, użyj następującego kodu:
WorkspacesExtensibility workSpace = this.Extensibility.Workspaces();
Dostęp do obszaru zapytań projektu w rozszerzeniu procesu
Jeśli tworzysz rozszerzenie w procesie, zamiast tego uzyskujesz dostęp do przestrzeni zapytań projektu, jak pokazano w poniższym przykładzie kodu. Jeśli nie utworzono specjalnie rozszerzenia w procesie, użyj fragmentu kodu w poprzedniej sekcji, aby uzyskać wystąpienie obiektu obszaru zapytania projektu.
W poniższym fragcie package
kodu reprezentuje wystąpienie pakietu AsyncPackage, klasę używaną w tworzeniu rozszerzeń programu Visual Studio. Metoda GetServiceAsync
jest stosowana do asynchronicznego pozyskiwania usługi zapytań z kontenera usługi programu Visual Studio.
IProjectSystemQueryService queryService = await package.GetServiceAsync<IProjectSystemQueryService, IProjectSystemQueryService>();
ProjectQueryableSpace workSpace = queryService.QueryableSpace;
Wykonywanie zapytań dotyczących systemu projektu dla projektu
Obiekt WorkspacesExtensibility
umożliwia wykonywanie zapytań dotyczących pojedynczego projektu, jeśli masz identyfikator GUID projektu. Zazwyczaj istnieją dwa identyfikatory GUID skojarzone z projektem, jeden reprezentujący typ projektu, a drugi, który jednoznacznie reprezentuje projekt. Unikatowy identyfikator GUID projektu można znaleźć w pliku rozwiązania lub w rozszerzeniu, które można wykonać w zapytaniu o Guid
właściwość, jak pokazano w następnej sekcji.
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> projectList = workspace
.ProjectsByProjectGuid(knownGuid)
.QueryAsync(cancellationToken);
Określanie parametrów projektu, które mają zostać uwzględnione w wyniku zapytania
Podczas wykonywania zapytań dotyczących systemu projektu można użyć With
klauzul w celu kontrolowania parametrów lub metadanych uwzględnionych w wynikach zapytania. Istnieje kilka prawidłowych sposobów określania, które parametry powinny być uwzględnione.
Przykład użycia oddzielnej With
klauzuli dla każdego parametru
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> allProjects = workSpace
.Projects
.With(p => p.Path)
.With(p => p.Guid)
.With(p => p.Kind) // DTE.Project.Kind
.With(p => p.Type) // VSHPROPID_ProjectType
.With(p => p.TypeGuid) // VSHPROPID_TypeGuid
.With(p => p.Capabilities)
.QueryAsync(cancellationToken);
await foreach (IQueryResultItem<IProjectSnapshot> project in allProjects)
{
var projectGuid = project.Value.Guid;
// Checking whether 'Capabilities' property has been retrieved.
// Otherwise, it can throw for projects which do not support it. (Like SQL projects)
bool capabilities = project.Value.PropertiesAvailableStatus.Capabilities;
}
Przykład użycia pojedynczej With
klauzuli w celu określenia wielu parametrów
Można również określić wiele żądanych parametrów w jednej With
klauzuli.
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> allProjects = workSpace
.Projects
.With(p => new { p.Path, p.Guid, p.Capabilities })
.QueryAsync(cancellationToken);
Przykład użycia klauzuli WithRequired
W przypadku korzystania z programu WithRequired
zwracane są tylko projekty z wymaganymi właściwościami.
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> projectWithFiles = workSpace
.Projects
.With(p => new { p.Path, p.Guid })
.WithRequired(p => p.Files.Where(f => f.FileName == "information.txt"))
.QueryAsync(cancellationToken);
Przykład, gdy nie określono żadnych właściwości
Jeśli nie określono żadnych właściwości, zwracany jest domyślny zestaw właściwości.
IAsyncEnumerable<IQueryResultItem<IPropertySnapshot>> properties = myproject
.PropertiesByName("RootNamespace", "AssemblyVersion")
.QueryAsync(cancellationToken);
Filtrowanie wyniku zapytania
Aby ograniczyć wyniki zapytania, istnieją dwa sposoby stosowania filtrowania warunkowego: Where
instrukcje i metody zapytań z wbudowanym filtrowaniem.
Przykład użycia klauzuli Where
Różne typy projektów obsługują różne zestawy możliwości. Za pomocą klauzuli Where
można filtrować projekty, które obsługują określone możliwości. Zapytania mogą zakończyć się niepowodzeniem, jeśli nie filtrujesz projektów, które obsługują odpowiednie możliwości.
Poniższy kod zwraca wartości Path
i Guid
wszystkich projektów internetowych platformy .NET Core w obszarze roboczym:
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> webProjects = workspace
.Projects
.Where(p => p.Capabilities.Contains("DotNetCoreWeb"))
.With(p => new { p.Path, p.Guid })
.QueryAsync(cancellationToken);
Przykład użycia RuleResultsByRuleName
filtrowania
Na poziomie poszczególnych projektów każdy projekt ma RulesResults
atrybut , który zawiera element RuleName
i Items
. Wywołanie RuleResultsByRuleName
interfejsu API może służyć do filtrowania według typu reguły w projekcie.
var results = await querySpace
.Projects
.With(p => p.Path)
.With(p => p.ActiveConfigurations
.With(c => c.RuleResultsByRuleName("CompilerCommandLineArgs")
.With(r => r.RuleName)
.With(r => r.Items
.With(i => i.Name))))
.ExecuteQueryAsync();
Przykład użycia ProjectsByCapabilities
filtrowania
Możesz również użyć metod zapytań, takich jak ProjectsByCapabilities
filtrowanie wbudowane w zapytanie.
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> webProjects = workspace
.ProjectsByCapabilities("DotNetCoreWeb | DotNetCoreRazor")
.With(p => new { p.Path, p.Guid })
.QueryAsync(cancellationToken);
Użyj zagnieżdżonych zapytań, aby określić żądane właściwości
Niektóre parametry są kolekcjami i można użyć zapytań zagnieżdżonych do podobnej specyfikacji i filtrowania dla tych kolekcji podrzędnych.
Przykład
W poniższym przykładzie zagnieżdżone zapytanie umożliwia filtrowanie i określanie kolekcji plików, które mają zostać dołączone do każdego projektu zwróconego przez zapytanie zewnętrzne.
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> projects = workspace
.ProjectsByCapabilities("CPS")
.With(p => new { p.Path, p.IsProjectFileSearchable })
.With(p => p.PropertiesByName("ApplicationIcon")) // Retrieve a single property, if it exists
.With(p => p.Files // Without any condition, retrieve all files in the project, but filter them
.Where(f => f.Extension == ".ico")
.With(f => new { f.Path, f.IsHidden }))
.QueryAsync(cancellationToken);
await foreach (IQueryResultItem<IProjectSnapshot> project in projects)
{
IPropertySnapshot property = project.Value.Properties.FirstOrDefault();
string? applicationIcon = (string?)property?.Value;
foreach (var iconFile in project.Value.Files)
{
string filePath = iconFile.Path;
bool isHidden = iconFile.IsHidden;
}
}
Pobieranie kolekcji podrzędnej przy użyciu metody Get
Model projektu programu Visual Studio zawiera kolekcje projektów i kolekcji podrzędnych, takich jak pliki lub możliwości projektu w projektach. Aby pobrać samą kolekcję podrzędną, możesz użyć klauzuli Get
. Podobnie jak w przypadku innych typów zapytań, klauzula Get
umożliwia używanie innych klauzul, takich jak klauzula With
do kształtowania lub ograniczania wyników.
IAsyncEnumerable<IQueryResultItem<IFileSnapshot>> files = workspace
.Projects
.Where(p => p.Guid == knownGuid)
.Get(p => p.Files
.With(f => new { f.Path, f.IsHidden, f.IsSearchable }))
.QueryAsync(cancellationToken);
await foreach (var file in files)
{
string filePath = file.Value.Path;
}
Wykonywanie zapytań o dodatkowe informacje z wcześniej zwróconego elementu
Możesz użyć wyników z poprzedniego zapytania jako podstawy dla dodatkowych zapytań.
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> allProjects = workSpace
.Projects
.With(p => p.Path)
.With(p => p.Guid)
.QueryAsync(cancellationToken);
await foreach (IQueryResultItem<IProjectSnapshot> project in allProjects)
{
// Gets child collections
IAsyncEnumerable<IQueryResultItem<IFileSnapshot>> files = project.Value
.Files
.With(f => new { f.Path, f.ItemType })
.QueryAsync(cancellationToken);
}
Modyfikowanie projektu
Wyniki zapytania są zwykle niezmienne. Interfejs API zapytań umożliwia również wprowadzanie zmian przy użyciu klauzuli w AsUpdatable
celu uzyskania dostępu do modyfikowalnych wersji wyników zapytania, dzięki czemu można wprowadzać zmiany w projektach i elementach projektu.
Przykład dodawania pliku do projektu w wyniku zapytania
IQueryResult<IProjectSnapshot> updatedProjects = workSpace
.ProjectsByProjectGuid(knownGuid)
.AsUpdatable()
.CreateFile("AdditionalInformation.txt", textContent)
.ExecuteAsync(cancellationToken);
Przykład dodawania pliku do wcześniej zwróconego projektu
IQueryResult<IProjectSnapshot> updatedProjects = myproject
.AsUpdatable()
.CreateFile("AdditionalInformation2.txt", textContent)
.ExecuteAsync(cancellationToken);
Przykład zmiany nazwy projektu
IQueryResult<IProjectSnapshot> updatedProjects = myproject
.AsUpdatable()
.Rename("NewProjectName", textContent)
.ExecuteAsync(cancellationToken);
Zapytanie o właściwości projektu
Klauzulę Get
można użyć do wykonywania zapytań dotyczących właściwości projektu. Poniższe zapytanie zwraca kolekcję IPropertySnapshot
zawierającą wpisy dla dwóch żądanych właściwości. IPropertySnapshot
zawiera nazwę właściwości, nazwę wyświetlaną i wartość w danym momencie.
// We assume that we can find the "RootNamespace" property in the result.
// However it isn't true from query API point of view.
// The query tries to retrieve items based on the condition, and if there is no such item, it will run successfully, only without returning items.
IAsyncEnumerable<IQueryResultItem<IPropertySnapshot>> properties = myProject
.AsQueryable()
.Get(p => p.PropertiesByName("RootNamespace", "AssemblyVersion"))
.QueryAsync(cancellationToken);
Wykonywanie zapytań o rozwiązania
Oprócz pracy z projektami, jak pokazano wcześniej, można użyć podobnych technik do pracy z rozwiązaniami.
IAsyncEnumerable<IQueryResultItem<ISolutionSnapshot>> solutions = workSpace
.Solutions
.With(s => new { s.Path, s.Guid, s.ActiveConfiguration, s.ActivePlatform })
.QueryAsync(cancellationToken);
Wykonywanie zapytań dotyczących folderów rozwiązań
Podobnie można użyć klauzuli Get
do wykonywania zapytań dotyczących folderów rozwiązań. Właściwość IsNested
umożliwia dołączanie lub wykluczanie folderów zagnieżdżonych z wyników. Eksplorator rozwiązań mogą mieć zagnieżdżone foldery, takie jak ustawienie konfiguracji lub zasoby.
IAsyncEnumerable<IQueryResultItem<ISolutionFolderSnapshot>> solutionFolders = workSpace
.Solutions
.Get(s => s.SolutionFolders)
.With(folder => folder.Name)
.With(folder => folder.IsNested)
.With(folder => folder.VisualPath) // it's a relative (virtual) path to represent how the folder is nested.
.QueryAsync(cancellationToken);
Ten przykład pobiera wszystkie zagnieżdżone foldery rozwiązań, projekty, pliki wewnątrz folderu rozwiązania (nie są rekursywnie zagnieżdżone):
IAsyncEnumerable<IQueryResultItem<ISolutionSnapshot>> solutionFoldersWithExtraInformation = mySolutionFolder
.AsQueryable()
.With(folder => folder.Files
.With(f => f.Path))
.With(folder => folder.Projects
.With(p => new { p.Name, p.Guid }))
.With(folder => folder.SolutionFolders
.With(nested => nested.Name))
.QueryAsync(cancellationToken);
Ten przykład pobiera wszystkie cyklicznie zagnieżdżone foldery rozwiązań. Jest VisualPath
to ścieżka wyświetlana w Eksplorator rozwiązań.
string visualPath = mySolutionFolder.VisualPath;
IAsyncEnumerable<IQueryResultItem<ISolutionFolderSnapshot>> recursivelyNestedFolders = await workSpace
.Solutions
.Get(s => s.SolutionFolders)
.Where(f => f.VisualPath.StartsWith(visualPath) && f.VisualPath != visualPath)
.With(f => f.Name)
.QueryAsync(cancellationToken);
Wyliczanie plików źródłowych z dodatkowymi informacjami w projekcie
Oto przykład wyliczania wszystkich plików xaml w projekcie i jego generatorze kodu:
IAsyncEnumerable<IQueryResultItem<IFileSnapshot>> files =
workSpace.ProjectsByProjectGuid(knownGuid)
.Get(p => p.Files)
.Where(file => file.Extension == ".xaml")
.With(file => file.Path)
.With(file => file.PropertiesByName("Generator"))
.QueryAsync(cancellationToken);
Innym przykładem jest rozpoczęcie od projektu zwróconego z poprzedniego zapytania:
IAsyncEnumerable<IQueryResultItem<IFileSnapshot>> files = myProject
.FilesEndingWith(".xaml") // use built-in filter instead of 'Where' condition
.With(file => file.Path)
.With(file => file.PropertiesByName("Generator"))
.QueryAsync(cancellationToken);
Możesz też pobrać wszystkie pliki zawartości, które nie są skompilowane, które są wymagane w czasie wykonywania, takie jak pliki HTML i CSS.
IAsyncEnumerable<IQueryResultItem<IFileSnapshot>> files =
myProject.FilesWithItemTypes("Content")
.With(file => file.Path)
.QueryAsync(cancellationToken);
Lub wyliczyć wszystkie pliki z określonym rozszerzeniem, takie jak pliki schematu XML (.xsd
pliki) we wszystkich projektach:
IAsyncEnumerable<IQueryResultItem<IFileSnapshot>> schemaFiles =
workSpace.Projects
.Get(proj => proj.FilesEndingWith(".xsd"))
.With(file => file.Path)
.QueryAsync(cancellationToken);
await foreach (IQueryResultItem<IFileSnapshot> fileResult in schemaFiles)
{
DoSomething(fileResult.Value.Path);
}
Wykonywanie zapytań dotyczących projektów, które są właścicielem określonego pliku źródłowego
Projekty i foldery zawierają informacje o plikach, które są ich właścicielami lub zawierają, dzięki czemu można użyć WithRequired
klauzuli do wykonywania zapytań dotyczących projektów zawierających określone pliki.
Przykład znajdowania projektów, które są właścicielem danego pliku
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> projects = workspace
.Projects
.WithRequired(proj => proj.FilesByPath(myFilePath))
.With(proj => proj.Guid)
.QueryAsync(cancellationToken);
Przykład znajdowania folderów rozwiązań zawierających dany plik
IAsyncEnumerable<IQueryResultItem<ISolutionFolderSnapshot>> solutionFolders = workspace
.Solutions
.Get(s => s.SolutionFolders)
.WithRequired(folder => folder.FilesByPath(myFilePath))
.With(folder => folder.Name)
.With(folder => folder.Guid)
.QueryAsync(cancellationToken);
Wykonywanie zapytań o konfiguracje projektu i ich właściwości
Projekty mają ConfigurationDimension
właściwość , której można użyć do znajdowania informacji o konfiguracji projektu. Informacje o konfiguracji projektu odnoszą się do konfiguracji kompilacji projektu (na przykład Debug
i Release
).
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> projects = workspace
.Projects
.With(p => new { p.Guid, p.Name })
.With(p => p.Configurations
.With(c => c.Name)
.With(c => c.PropertiesByName("OutputPath"))
.With(c => c.ConfigurationDimensions)) // ConfigurationDimension is essentially Name, Value pairs, both are default properties.
.QueryAsync(cancellationToken);
await foreach (IQueryResultItem<IProjectSnapshot> project in projects)
{
foreach (var configuration in project.Value.Configuration)
{
// ...
}
}
Wykonywanie zapytań dotyczących odwołań do projektu
Możesz również wykonać zapytanie w celu znalezienia projektów odwołujących się do danego projektu.
Przykład znajdowania wszystkich projektów, do których odwołuje się bieżący projekt
IAsyncEnumerable<IQueryResultItem<IProjectReferenceSnapshot>> projectReferences = myProject
.ProjectReferences
.With(r => r.ProjectGuid)
.With(r => r.ReferencedProjectId)
.QueryAsync(cancellationToken);
Przykład znajdowania wszystkich projektów odwołującej się do bieżącego projektu
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> projects = workSpace
.Projects
.With(p => p.Guid)
.WithRequired(p => p.ProjectReferences
.Where(r => r.ProjectGuid == knownGuid))
.QueryAsync(cancellationToken);
Zapytanie dotyczące odwołań do pakietu
Podobnie możesz wykonywać zapytania dotyczące odwołań pakietów NuGet.
Przykład znajdowania wszystkich pakietów, do których odwołuje się bieżący projekt
IAsyncEnumerable<IQueryResultItem<IProjectConfigurationSnapshot>> configurationsWithPackageReferences = myProject
.ActiveConfigurations
.With(c => c.Name)
.With(c => c.PackageReferences
.With(p => new { p.Name, p.Version }))
.QueryAsync(cancellationToken);
Przykład znajdowania wszystkich projektów odwołującej się do określonego pakietu NuGet
string packageName = "Newtonsoft.Json";
IAsyncEnumerable<IQueryResultItem<IProjectSnapshot>> projects = workSpace
.Projects
.With(p => p.Guid)
.WithRequired(p => p.ActiveConfigurations
.WithRequired(c => c.PackageReferences
.Where(package => package.Name == packageName)))
.QueryAsync(cancellationToken);
Wykonywanie zapytań dotyczących grup danych wyjściowych projektu
Konfiguracje projektu zawierają informacje o grupach danych wyjściowych projektu.
// From our list of active configurations, we need to get the first one in the list
IAsyncEnumerable<IQueryResultItem<IProjectConfigurationSnapshot>> configurations = myProject
.ActiveConfigurations
.QueryAsync(cancellationToken);
IProjectConfigurationSnapshot myConfiguration = null;
await foreach (IQueryResultItem<IProjectConfigurationSnapshot> config in configurations)
{
myConfiguration = config.Value;
break;
}
// A multi-target project may have multiple active configurations
IAsyncEnumerable<IQueryResultItem<IOutputGroupSnapshot>> outputGroups = myConfiguration
.OutputGroupsByName("Built", "Symbols")
.With(g => g.Name)
.With(g => g.Outputs)
.QueryAsync(cancellationToken);
Wykonywanie zapytań dotyczących projektów startowych
Rozwiązanie zawiera zestaw projektów startowych, które można wykonać jako plik wykonywalny.
// A query to get the list of startup project's name and path
var result = await this.QueryableSpace.Solutions
.With(solution => solution.StartupProjects
.With(startupproject => startupproject.Name)
.With(startupproject => startupproject.Path))
.QueryAsync(CancellationToken.None);
Akcja ustawiania projektu startowego
Za pomocą interfejsu API zapytań projektu możesz również wybrać projekty, które są wykonywane. W poniższym przykładzie pokazano, jak można ustawić dwie ścieżki projektu jako projekty startowe.
// A query to set the startup project
var result = await this.QueryableSpace.Solutions
.With(solution => solution.StartupProjects)
.AsUpdatable()
.SetStartupProjects("full\\path\\to\\project1.csproj",
"full\\path\\to\\project2.csproj")
.ExecuteAsync(CancellationToken.None);
Wykonywanie zapytań o konfiguracje rozwiązań
Konfiguracja rozwiązania to kolekcja projektów uwzględnionych w kompilacji, gdy konfiguracja jest aktywna. W poniższym przykładzie pokazano, jak wykonywać zapytania dotyczące nazw konfiguracji rozwiązania.
var results = await this.Extensibility.Workspaces().QuerySolutionAsync(
solution => solution.With(solution => solution.SolutionConfigurations
.With(c => c.Name)),
cancellationToken);
Przykład dodawania konfiguracji rozwiązania
Metoda AddSolutionConfiguration
przyjmuje trzy parametry:
- Pierwszy parametr to nowa nazwa nowej konfiguracji rozwiązania. W tym przykładzie nowa konfiguracja rozwiązania będzie nazywana .
Foo
- Następnym parametrem jest konfiguracja, na której powinna być oparta nowa konfiguracja. Poniżej nowa konfiguracja rozwiązania jest oparta na istniejącej konfiguracji
Debug
rozwiązania . - Na koniec wartość logiczna reprezentuje, czy konfiguracja rozwiązania powinna być propagowana.
await this.Extensibility.Workspaces().UpdateSolutionAsync(
solution => solution.Where(solution => solution.BaseName == "mySolution"),
solution => solution.AddSolutionConfiguration("Foo", "Debug", false),
cancellationToken);
Przykład usuwania konfiguracji rozwiązania
DeleteSolutionConfiguration
to wywołanie interfejsu API, które usuwa konfigurację rozwiązania. W poniższym przykładzie konfiguracja rozwiązania o nazwie Foo
została usunięta.
await this.Extensibility.Workspaces().UpdateSolutionAsync(
solution => solution.Where(solution => solution.BaseName == "mySolution"),
solution => solution.DeleteSolutionConfiguration("Foo"),
cancellationToken);
Zapytanie akcji w celu załadowania/zwolnienia projektu
Jeśli projekt musi zostać zwolniony, należy określić rozwiązanie i ścieżkę do żądanego projektu do zwolnienia. W poniższym przykładzie użyto Extensibility.Workspaces().UpdateSolutionAsync
metody do zaktualizowania rozwiązania i UnloadProject
zwolnienia projektu.
await this.Extensibility.Workspaces().UpdateSolutionAsync(
solution => solution.Where(solution => solution.BaseName == "MySolution"),
solution => solution.UnloadProject("full\\path\\to\\project.csproj"),
cancellationToken);
AsUpdatable
można również użyć do załadowania lub zwolnienia projektu.
var result = await querySpace.Solutions
.AsUpdatable()
.LoadProject("full\\path\\to\\project.csproj")
.ExecuteAsync();
Zapytanie dotyczące akcji w celu tworzenia rozwiązań/projektów
W zapytaniu projektu masz również możliwość wywoływania akcji kompilacji na poziomie projektu lub rozwiązania. Te akcje kompilacji obejmują:
BuildAsync
RebuildAsync
CleanAsync
DebugLaunchAsync
LaunchAsync
Tworzenie poziomu rozwiązania
Kompilowanie na poziomie rozwiązania spowoduje skompilowanie wszystkich projektów, które są ładowane do rozwiązania. Poniżej przedstawiono przykład tworzenia rozwiązania.
var result = await querySpace.Solutions
.BuildAsync(cancellationToken);
Kompilowanie na poziomie projektu
Podczas kompilowania na poziomie projektu określ wybrany projekt, który chcesz skompilować. W poniższym przykładzie jest to elementIProjectSnapshot
, myProject
który zostanie utworzony.
var result = await myProject.BuildAsync(cancellationToken);
Zapytanie akcji w celu zapisania rozwiązań/projektów
SaveAsync
można używać na poziomie projektu lub rozwiązania.
Zapisywanie na poziomie rozwiązania
var result = await querySpace.Solutions
.SaveAsync(cancellationToken);
Zapisywanie na poziomie projektu
myProject
jest projektem IProjectSnapshot
docelowym, który ma zostać zapisany.
var result = await myProject.SaveAsync(cancellationToken);
Zapytanie akcji do śledzenia zmian zapytań
TrackUpdatesAsync
można używać na poziomie projektu lub rozwiązania. Służy do śledzenia zmian w projekcie lub rozwiązaniu.
W tym przykładzie TrackUpdatesAsync
wywoływana jest właściwość Files projektu z zastosowanym filtrem nazwy pliku. Oznacza to, że będzie śledzić zmiany nazw plików w projekcie. Wystąpienie TrackerObserver jest przekazywane w celu otrzymywania powiadomień o zmianach.
var projects = await querySpace.Projects.ExecuteQueryAsync(cancellationToken: CancellationToken.None);
var singleProject = projects.FirstOrDefault();
var unsubscriber = await singleProject
.Files
.With(f => f.FileName)
.TrackUpdatesAsync(new TrackerObserver(), CancellationToken.None);
Jest TrackerObserver
to klasa prywatna, która implementuje interfejs IObserver, w szczególności dla programu IQueryTrackUpdates<IFileSnapshot>
. Jest to przeznaczone do odbierania powiadomień o śledzeniu aktualizacji do migawek plików.
private class TrackerObserver : IObserver<IQueryTrackUpdates<IFileSnapshot>>
{
public void OnCompleted()
{
...
}
public void OnError(Exception error)
{
...
}
public void OnNext(IQueryTrackUpdates<IFileSnapshot> value)
{
...
}
public override int GetHashCode()
{
...
}
}
Zapytanie akcji do pominięcia
Skip
Może służyć do pomijania N wyników z zapytania.
W tym przykładzie kodu pierwszy wynik zapytania zostanie pominięty. Jeśli na przykład w rozwiązaniu wystąpiły trzy projekty, pierwszy wynik zostanie pominięty, a zapytanie zwróci dwa pozostałe projekty. Uwaga: zamówienie nie jest gwarantowane.
var projects = await queryableSpace.Projects
.With(proj => proj.Name)
.Skip(1)
.ExecuteQueryAsync(new CancellationToken());
Następne kroki
Aby zapoznać się ze słowami kluczowymi i pojęciami dotyczącymi interfejsu API zapytań projektu, zobacz Project Query Concepts (Pojęcia dotyczące zapytań projektu).
Przejrzyj kod rozszerzenia korzystającego z interfejsu API zapytań projektu w artykule VSProjectQueryAPISample.