Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Feb 03 21:02
    amaitland commented #162
  • Feb 02 23:39
    drewnoakes closed #162
  • Feb 02 23:39
    drewnoakes commented #162
  • Feb 02 23:39
    drewnoakes closed #316
  • Feb 02 23:39
    drewnoakes commented #316
  • Feb 01 05:47
    amaitland commented #162
  • Feb 01 05:38
    amaitland commented #162
  • Jan 31 10:52

    drewnoakes on master

    Fix heading formatting in IDyna… Merge pull request #331 from dr… (compare)

  • Jan 31 10:52
    drewnoakes closed #331
  • Jan 31 10:52
    drewnoakes commented #328
  • Jan 31 10:30

    drewnoakes on master

    Rename UnitTestContainer to Tes… Merge pull request #330 from Kr… (compare)

  • Jan 31 10:30
    drewnoakes closed #330
  • Jan 31 10:30
    drewnoakes closed #328
  • Jan 31 10:30
    drewnoakes commented #328
  • Jan 31 10:15

    drewnoakes on master

    Update IProjectTreePropertiesPr… Merge pull request #327 from dr… (compare)

  • Jan 31 10:15
    drewnoakes closed #327
  • Jan 31 10:15

    drewnoakes on master

    Fix broken link Merge pull request #332 from dr… (compare)

  • Jan 31 10:15
    drewnoakes closed #332
  • Jan 31 00:26
    drewnoakes opened #332
  • Jan 05 23:34
    drewnoakes opened #331
jp2masa
@jp2masa
it doesn't need to be in that specific folder, but make sure you have the rules in the right path too
Kirk Fertitta
@kfertitta
@jp2masa Thanks. Didn't know the rules had to be co-located with the targets. When I put both in the Desktop folder, it seems to work fine.
jp2masa
@jp2masa
the path is specified in the targets file
Kirk Fertitta
@kfertitta
Yeah, but even if you point to the right locations, they can't be separate locations.
The failure I was getting was if the targets were on the Desktop and the rules were in LocalAppData.
Makes sense now...of course :-)
Kirk Fertitta
@kfertitta
Is there any way to get an IServiceProvider from a ConfiguredProject or UnconfiguredProject?
This would be for a component that is explicitly created, as opposed to created by MEF (where I could, of course, simply Import).
Kirk Fertitta
@kfertitta
I know, from experience, that when using IVsHierarchy, it's not generally safe to do so, such as when the project is in an unloaded state.
Adrian Vinca
@adrianvmsft
Well you should be able to just import the Visual Studio global service provider
[Import]
private SVsServiceProvider ServiceProvider { get; set; }
Kirk Fertitta
@kfertitta

@adrianvmsft Thanks for the reply. But, this class is not created via MEF -- it's explicitly created, so how does that Import get satisfied?
Are you instead suggesting that I add the Import to my specific unconfigured project (i.e. the MyUnconfiguredProject type generated in the SDK samples), and then do something like the following:

var p = this.UnconfiguredProject.Services.ExportProvider.GetExportedValue<UnconfiguredProject>();
var sp = p.ServiceProvider;

That would certainly work, but thought perhaps there was a more direct method.

Kirk Fertitta
@kfertitta
Sorry, the first line in the above should be:
var p = this.UnconfiguredProject.Services.ExportProvider.GetExportedValue<MyUnconfiguredProject>();
Kirk Fertitta
@kfertitta
Do I need to export an IProjectTreeProvider to have my custom project system have a "References" node, or is having the following adequate:
<ProjectCapability Include="ReferencesFolder" />
Kirk Fertitta
@kfertitta
Ok, it looks like you need both "ReferencesFolder" and "ProjectReferences" (for example).
Though, I do see that "ReferencesFolder" is deprecated.
jp2masa
@jp2masa
you should try using DependenciesTree instead I think, not sure if it will work though...
Kirk Fertitta
@kfertitta
@jp2masa , why is that preferred -- just because it can serve as a root for project references, NuGets, etc.?
If I declare both "ReferencesFolder" and "ProjectReferences", then I do see the References node and the Add Reference command, both on the project node and the References node.
And, when executing "Add Reference" the Add Reference Dialog appears properly with only Projects available.
This is the behavior I want, but if there are advantages to DependenciesTree even for project systems that only support project references, I'd be interested.
Well, @jp2masa , DependenciesTree works identically, so I'll just use that (since it's not marked "deprecated", if for no other reason).
Do you know how to intercept the project reference item creation so that I can add some custom item metadata my build system needs?
jp2masa
@jp2masa
I think you can subscribe to item updates
Kirk Fertitta
@kfertitta
Ah, ok. Thanks. Will dig into that.
Kirk Fertitta
@kfertitta
So, @jp2masa , is a project tree provider required to populate the child nodes of the "Dependencies" node?
After adding a reference from my custom project system to a C# class library, the project file is properly updated, but nothing appears under "Dependencies".
Not sure if I should expect that to be built in or not.
I see that the Dotnet Project System seems to build it up from scratch completely.
jp2masa
@jp2masa
right, that capability is owned by the .NET project system
I think it subscribes to updates on ProjectReferences and updates the tree
Kirk Fertitta
@kfertitta
Yeah, I'm digging in now.
I'm also looking at your provider in Cosmos.
In your Plugs provider, I'm curious as to how you know the following is the Dependencies node:
        private Task ItemsChangedAsync(IProjectVersionedValue<IProjectCatalogSnapshot> snapshot)
        {
            var nowait = SubmitTreeUpdateAsync(
                (treeSnapshot, configuredProjectExports, cancellationToken) =>
                {
                    var dependenciesNode = treeSnapshot.Value.Tree;

                    if (!cancellationToken.IsCancellationRequested)
                    {
                        dependenciesNode = BuildTree(dependenciesNode, snapshot.Value, cancellationToken);
                    }

                    return Task.FromResult(new TreeUpdateResult(dependenciesNode, lazyFill: false));
                });

            return Task.CompletedTask;
        }
jp2masa
@jp2masa
that's a different node
Kirk Fertitta
@kfertitta
Ah, ok. Thanks. Won't interpret it so literally.
Examples of providers are a bit scarce.
Kirk Fertitta
@kfertitta
So, @jp2masa , what's the real benefit of declaring the "Dependencies" (or, for that matter, the "ReferencesFolder") capabilities, if you have to write a project tree provider anyway to populate the children?
The provider could easily create the "Dependencies" root node anyway.
Or am I missing something?
jp2masa
@jp2masa
you shouldn't have to write the provider
Kirk Fertitta
@kfertitta
But, this is a non-.NET, custom project system.
jp2masa
@jp2masa
do you have both a ProjectReference and ResolvedProjectReference rules?
Kirk Fertitta
@kfertitta
No. Lemme try that.
I have just ProjectReference at present.
jp2masa
@jp2masa
also, do you import Microsoft.Common.CurrentVersion.targets?
Kirk Fertitta
@kfertitta
Hmmn, not doing that in my small sample project.
Will change that too.
Kirk Fertitta
@kfertitta
@jp2masa , Ok, sadly, no joy yet.
I've added XAML rules files for both ProjectReference and ResolvedProjectReference and bring both in via the targets file.
I'm importing Microsoft.Common.targets (also tried .CurrentVersion.targets).
I'm declaring the "ReferencesFolder" and "ProjectReferences" folder. (also tried "Dependencies")
Still see just a References node and no children.
Am I supposed to be subscribing to any item changes at this point (I'm not)?
jp2masa
@jp2masa
this is how it works I think:
Kirk Fertitta
@kfertitta
Thanks @jp2masa . Indeed, I've done exactly those steps.
Must be missing something else simple.
Kirk Fertitta
@kfertitta
If you do those same steps to the WindowsScript sample, it also does not show any child reference nodes.
Kirk Fertitta
@kfertitta

Can anyone comment on the practical difference between accessing the active ConfiguredProject in the following two ways (other than the obvious async different):

UnconfiguredProject.Services.ActiveConfiguredProjectProvider.ActiveProjectConfiguration

versus

UnconfiguredProject.GetSuggestedConfiguredProjectAsync()
Kirk Fertitta
@kfertitta

I'm trying to read the value of a project property that is defined inside a target, like so:

  <Target Name="Test">
    <PropertyGroup>
      <Foo>Kirk</Foo>
    </PropertyGroup>
  </Target>

Thus, the target must run before the Foo property has a value. In our MPFProj-based project system, this worked fine -- just run the target and read the property, as per normal. MPFProj uses the MSBuild API directly.

In an attempt to do the same in our new CPS-based project, we use IBuildProject.BuildAsync and GetEvaluatedPropertyValueAsync. However, the Foo property returns an empty string.

Here is the code:

                        var buildResult = await configuredProject.Services.Build.BuildAsync(new[] { "Test" }, cancellationToken: default, includeUnsavedChanges: true);
                        Debug.Assert(buildResult.OverallResult == BuildResultCode.Success);

                        var f1 = await configuredProject.Services.ProjectPropertiesProvider.GetCommonProperties().GetEvaluatedPropertyValueAsync("Foo");

                        using (var access = await projectLockService.ReadLockAsync())
                        {
                            var project = await access.GetProjectAsync(configuredProject);
                            var projectInstance = BuildManager.DefaultBuildManager.GetProjectInstanceForBuild(project);
                            var success = projectInstance.Build("Test", loggers: null);
                            Debug.Assert(success);

                            var f2 = projectInstance.GetPropertyValue("Foo");
                        }

In the above f1 is an empty string, while f2 correctly prints out the Foo property's value of "Kirk".

Any thoughts on why? It makes me nervous about using IBuildProject as opposed to MSBuild directly.

Thanks in advance.

Kirk Fertitta
@kfertitta
Anybody out there?
jp2masa
@jp2masa
@kfertitta do you still need help with that? the easiest way would be returning the value from a target I think, you can also create a rule and set the data source to the target results if you want
Kirk Fertitta
@kfertitta
@jp2masa Thanks for chiming in. This is still unresolved and feels important/fundamental.
Trouble is, this is a general usage issue as I have LOTS of target-scoped properties like this.
It may be more practical to forego IBuildProject altogether if it can't handle this and just use the MSBuild API.
I can sorta see what's going on -- the ConfiguredProject is probably tied to a ProjectInstance under the covers, and that's not getting updated when you do a build.
Feels like there should be a way to "kick it" and either get an updated ConfiguredProject instance or something.
It's all layered on top of MSBuild, so just feels like I'm missing something.
jp2masa
@jp2masa
I don't think that you're supposed to get properties from targets that often... anyway, did you try using this: https://github.com/Microsoft/VSProjectSystem/blob/master/doc/automation/obtaining_the_MSBuild.Project_from_CPS.md ?
Kirk Fertitta
@kfertitta
@jp2masa , Indeed, I did exactly that. See the code snippet above. I take the project obtained in that fashion and feed it to the MSBuild API in order to get the correct results.
But, there are many actions that could cause properties to change, so I'm unclear on when/how/if the ConfiguredProject is updated in general if this doesn't work.
jp2masa
@jp2masa
that's why you have to acquire the lock I think, so that the project that you get is always up-to-date
Kirk Fertitta
@kfertitta
Yeah, but after leaving the using, reading the properties again still returns an empty string.
I did think about the effect of the lock.
But, build doesn't require a lock, and lots of things can change as a result of a build. Item transforms, etc, etc.
jp2masa
@jp2masa
that's because targets are associated to building, and in VS the project isn't building, you just have a project instance
if you build a target, it wouldn't make sense to affect the instance I think?
Kirk Fertitta
@kfertitta
Well, it has to. And it does in MSBuild directly. The f2 variable prints the correct value -- the value of a property that's only defined in a target.
And MSBuild is underneath the ConfiguredProject.
jp2masa
@jp2masa
right, what I mean is that for example you build the same target multiple times, and that target appends something to a property, you would get the appended part multiple times, that's not what you want