Project.ProjectReferences shows no item instead of list of project dependencies - roslyn

I am using the following code to open solution, load the project and create the compilation.
var solution = await workspace.OpenSolutionAsync(solutionPath, new ConsoleProgressReporter());
Project valueObjectProject = solution.Projects.FirstOrDefault(proj => String.Equals(proj.Name,
"ValueObject", StringComparison.CurrentCultureIgnoreCase));
var bofCompilation = await valueObjectProject.GetCompilationAsync();
Issue: no of items in valueObjectProject.ProjectReferences and compilation.References is 0, which is not true. The property should show a list of projects on which the ValueObject project depends upon. But, I am getting list of all the microsoft assemblies which the project uses under valueObject.MetadataReferences and compilation.ExternalReferences
Currently, the Diagnostics shows multiple errors of type TypeNotFound because the referenced types are declared in different assemblies. I think this is because the compilation does not have project dependency information. Don't know what is going wrong.
any help would be highly appreciated.

Related

SingleFileGenerator / Run Custom Tool does not run for new vs2017 project type

I have a SingleFileGenerator that works correctly for old-style Visual Studio C# projects, but not at all for the new-style VS2017 C# projects. I've added the new guid to registration attributes and to the packagedef, but still no joy. For reference, this code generator acts on xml files with the extension .3schema, which is an xml file of our own invention...
[Guid("0BC6C7FE-28F7-4A64-A8F8-714FFC0F8FB4")]
[PackageRegistration(UseManagedResourcesOnly = true)]
[InstalledProductRegistration("TrilogySchemaGenerator", "Trilogy C# Schema Generator", "5.9")]
[CodeGeneratorRegistration(typeof(TrilogySchemaGenerator), "Trilogy C# Schema Generator", "{9A19103F-16F7-4668-BE54-9A1E7A4F7556}", GeneratesDesignTimeSource = true)]
[CodeGeneratorRegistration(typeof(TrilogySchemaGenerator), "Trilogy C# Schema Generator", vsContextGuids.vsContextGuidVCSProject, GeneratesDesignTimeSource = true)]
[ProvideObject(typeof(TrilogySchemaGenerator))]
public class TrilogySchemaGenerator : BaseCodeGeneratorWithValidation // base class implements IVsSingleFileGenerator
{
…
}
And the pkgdef:
[$RootKey$\Generators\{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}\.3schema]
#="TrilogySchemaGenerator"
[$RootKey$\Generators\{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\.3schema]
#="TrilogySchemaGenerator"
What step am I missing? Is there an additional registration required? Ideas of other things to try?
I've looked in the wrong place to solve my problem. It was not a problem with my SingleFileGenerator at all! But if you are building a SingleFileGenerator, please look to this answer for details of how to register it properly:
How to register "custom tool" with Visual Studio 2017 to make it work?
I used this excellent tool to convert my old projects to the new VS2017. I highly recommend:
https://www.nuget.org/packages/Project2015To2017.Migrate2017.Tool/
However, this tool does not deal well with custom build steps, of which my code generation is one. In my case, when I hand coded the custom build steps, I missed a reference to the noted line of XML:
<ItemGroup>
<XmlResource Include="Schema\T1TY2019.3schema">
--> <Generator>TrilogySchemaGenerator</Generator> <--
<LastGenOutput>T1TY2019.cs</LastGenOutput>
</XmlResource>
</ItemGroup>

Including specific style sheets or javascript in ember-cli-build

The problem
I am working on an Ember.js project which has different versions (products) for different clients. Though the functionality is more or less the same, the styling of each product differs big time. Hence we have "default" and product specific style sheets. I have been asked to modify the build code so that only the corresponding .css (.less) files are compiled into the final app.
Originally I was looking at this issue from the wrong side: I tried to exclude the folders containing the unnecessary files with little success. Only then did I realize that it makes more sense not to include the product specific files by default and add them to the tree during the build.
The solution
After changing my point of view I found out there is another way around. I changed the style sheets so that all the "default looks" went into an import-base.less and I created an import-[name_of_product].less for each of the products, with the latters containing the import statement to the default looks, so I only have one file to build. Using the outputPaths option in EmberApp and assuming that the name of the product is stored in the process environmental variable called FLAVOUR my code looks as follows.
// ember-cli-build.js
/* global require, module */
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function(defaults) {
// y u do dis
const options = { outputPaths: { app: { css: { app: false } } } };
const lessFileName = 'import-' + process.env.FLAVOUR.toLowerCase();
options.outputPaths.app.css[lessFileName] = 'assets/application.css'
const app = new EmberApp(defaults, options);
return app.toTree();
};
There is always something
The only problem with that code is that it still needs an app.less and that line of code or else the build fails, couldn't (haven't had time to) figure out a solution.
I also have to mention that the above solution doesn't resolve the original problem, which was:
How to exclude specific files from the working directory before using app.toTree() so that they wouldn't increase file size unnecessarily. Lux was so kind and pointed out that probably in-repo-addons are to be used for such purposes. Yet again, haven't had time to check. :(
I think you can just use funnel!
something like this:
return new Funnel(app.toTree(), {
include: ['**/*']
exclude: ['styles/*.css']
});
general you can do anything you can do in a Brocfile in your ember-cli-build.js!

WinRT API WIndows::System::Launcher::LaunchFileAsync() usage from C++

I'm trying to launch an image using WinRT API WIndows::System::Launcher::LaunchFileAsync().
Code snippet is as follows:
RoInitialize(RO_INIT_MULTITHREADED);
String^ imagePath = ref new String(L"C:\\Users\\GoodMan\\Pictures\\wood.png");
auto file = Storage::StorageFile::GetFileFromPathAsync(imagePath);
Windows::System::Launcher::LaunchFileAsync(file);
I'm getting this error from the LaunchFileAsync() API:
error C2665: 'Windows::System::Launcher::LaunchFileAsync' : none of
the 2 overloads could convert all the argument types
Can I please get help how to solve this. I'm very new to WinRT C++ coding .
The method GetFileFromPathAsync does not return a StorageFile, but it returns IAsyncOperation<StorageFile>^. What you have to do is convert the latter to the former, as follows:
using namespace concurrency;
String^ imagePath = ref new String(L"C:\\Users\\GoodMan\\Pictures\\wood.png");
auto task = create_task(Windows::Storage::StorageFile::GetFileFromPathAsync(imagePath));
task.then([this](Windows::Storage::StorageFile^ file)
{
Windows::System::Launcher::LaunchFileAsync(file);
});
Generally all Windows Store app framework methods that end in Async will return either an IAsyncOperation, or a task. These methods are what are known as asynchronous methods, and require some special handling. See this article for more info: Asynchronous programming in C++ .
So now everything is great, correct? Well, not quite. There is another issue with your code. It is that when you run the code above, you will get an access-denied error. The reason is that Windows Store Apps are sandboxed, and you cannot generally access just any file on the filesystem.
You are in luck, though, because you are trying to access a file in your Pictures folder. The Pictures folder is a special folder that Windows Store apps have access to. You can get at it using the KnownFolders class:
using namespace concurrency;
Windows::Storage::StorageFolder^ pictures =
Windows::Storage::KnownFolders::PicturesLibrary;
auto task = create_task(pictures->GetFileAsync("wood.png"));
task.then([this](Windows::Storage::StorageFile^ file)
{
Windows::System::Launcher::LaunchFileAsync(file);
});
Note that in order to access the Pictures folder your application has to declare it in the project manifest. To do so, double click on the Package.appmanifest file in the project "tree" in Visual Studio, and select the Capabilities tab. Then under Capabilities, check Pictures Library.

Roslyn Workspace API : Emiting Wpf and Silverlight Projects

I try Emit each project in this solution.
I wonder why there is a problem with Emiting "Wpf" and "Silverlight" projects. I can understand that I can't Emit Console Project that I am currently executing.
How I can add missing references?
Here is my code.:
public static async Task EmitProject(Project proj)
{
var c = await proj.GetCompilationAsync();
var r = c.Emit("my" + proj.Name );
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(r.Success + " " + proj.Name);
if (!r.Success)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(r.Diagnostics.First(k => k.WarningLevel == 0));
}
}
Silverlight and WPF projects have a somewhat complicated build process, where some of the code is generated at build time by things like the XAML Markup Compiler. Calling Emit doesn't trigger that code to run - it just represents a single call to the CSC task in MSBuild.
Most of the time OpenSolutionAsync actually causes the build to progress far enough that the invocation of CSC will work, but apparently not for these project types.
For the ConsoleApplication, the issue is that it references a PCL, and the facade references are not being added correctly.
Can you file an issue at http://github.com/dotnet/roslyn for us to investigate?

Visual Studio Addin - Get Name\Path of binary of a c++ project?

I want to get the binary name of a C++ Project with a Visual Studio C# Addin.
I googled and found, that the the EnvDTE.Configuration.properties should have a element called "AssemblyName" but C++ projects do not seem to have this element.
Did somebody know where could I get this information inside a visual studio addin?
For VC++ projects you need to get access to the VCConfiguration object which you should be able to get at from the EnvDTE.Project's Object property like:
EnvDTE.Project project = ...
VCProject vcProj = (VCProject)project.Object;
IVCCollection configs = (IVCCollection)vcProj.Configurations;
VCConfiguration config = (VCConfiguration)configs.Item(configName); // like "Debug"
At that point with the VCConfiguration how exactly to get at the correct properties depends on your set up. You can access the the VCLinkerTool from the Tools property and get at the OutputFile and other properties. Or, if you use the newer inherited property sheets you may access those through the Rules property.
IVCCollection tools = (IVCCollection)config.Tools;
VCLinkerTool linkTool = (VCLinkerTool)tools.Item("Linker Tool");
string outputFile = linkTool.OutputFile;
// -------
IVCRulePropertyStorage ruleStorage = config.Rules.Item(ruleName);
string outputFile = ruleStorage.GetEvaluatedPropertyValue("TargetName");
In order to get the complete path of the binary, follow the steps as #Chadwick said to get the VCConfiguration object. And then, just use the following line of code:
//returns the complete binary name including path as a string
var primaryOutput = config.PrimaryOutput;