I installed the folowing assembly with NuGet Package Manager in Visual Studio 2017
Microsoft.Build;
Microsoft.Build.Framework.
Microsoft.Build.Utilities.Core
All is in version 15
I want to build a c++ project with Msbuild
public static void Build(string namePerozhe)
{
Logger l = new Logger();
ProjectCollection pc = new ProjectCollection();
pc.DefaultToolsVersion = "15.0";
pc.Loggers.Add(l);
Dictionary<string, string> GlobalProperty = new Dictionary<string, string>();
GlobalProperty.Add("Configuration", "Release");
GlobalProperty.Add("Platform", "Win32");
BuildRequestData buildRequest = new BuildRequestData(namePerozhe, GlobalProperty, null, new[] { "Build" }, null);
BuildParameters buildParameters = new BuildParameters(pc)
{
OnlyLogCriticalEvents = false,
DetailedSummary = true,
Loggers = new List<Microsoft.Build.Framework.ILogger> { l }.AsEnumerable()
};
var result = BuildManager.DefaultBuildManager.Build(buildParameters, buildRequest);
}
But i get the below error :
The "SetEnv" task could not be loaded from the assembly
C:\Program Files\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets\
Microsoft.Build.CppTasks.Common.dll.
Could not load file or assembly 'Microsoft.Build.Utilities.Core, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
The system cannot find the file specified.
Confirm that the declaration is correct, that the assembly and all its dependencies are available,
and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
when i build this project in visual studio it will build with no error . but when i want to build it programmatically this error will throw up.
there is another question that don't have any answer that help me .
I had to do three main steps:
Download the version 15+ Microsoft.Build packages from NuGet. The ones that aren't from NuGet are out of date.
Download the Microsoft.Build.Runtime package. If you don't download that package, your project might still build, but it'll crash at runtime on LoadProject.
Hooked up bindingRedirects in my app.config. See: https://developercommunity.visualstudio.com/content/problem/24545/microsoftbuildcpptaskscommon-references-incorrect.html
I had similar problem and solved it by adding bindingRedirect to app.config for every msbuild assembly.
Just look at C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe.config and copy necessary blocks to your app.config.
make sure you have below blocks in your C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\msbuild.exe.config
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Tasks.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.0.0.0"/>
</dependentAssembly>
Or you may use your own msbuild.exe, make sure you point your env PATH to the right one.
Related
our software is written in C# running .Net-Framework 4.7.2. Our users can use a script editor built into our software to write their own user scripts with C#. To realize that, we are using the .Net component CodeDomProvider. To make it possible to work with JSON in an easy way, we want to make Newtonsoft.Json.dll be referenced in our user's scripts. This is done by adding the reference to the CompilerParameters of the CodeDomProvider. The Newtonsoft.Json is added to my application by the usage of the newest Newtonsoft.Json NuGet package (12.0.3).
Here a minimum example of this setup:
using System;
using System.CodeDom.Compiler;
using System.IO;
namespace ScriptingUnix
{
class Program
{
static void Main(string[] args)
{
try
{
string output;
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
output = "/tmp/MyUnixTest.dll";
}
else
{
output = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyUnixTest.dll");
}
CompilerParameters parameters = new CompilerParameters
{
GenerateInMemory = false,
IncludeDebugInformation = true,
OutputAssembly = output
};
using (CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp"))
{
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("Newtonsoft.Json.dll");
CompilerResults results = codeProvider.CompileAssemblyFromSource
(
parameters,
"using System;\nusing Newtonsoft.Json.Serialization;\nusing Newtonsoft.Json.Linq;\n class Program\r\n{\r\n static void Main(string[] args)\r\n {\r\n \r\n }\r\n}"
);
foreach (CompilerError compilerError in results.Errors)
{
Console.WriteLine(compilerError);
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadLine();
}
}
}
This setup works fine under .Net Framework on Windows. The problem is, that we are also providing a version of our software running with Mono on (Arch)-Linux (Linux 4.19.80-1-ARCH armv7l, Mono JIT compiler version 6.0.0 (makepkg/6256b82d62f Wed 25 Sep 2019 05:04:08 AM UTC)), where running the same code with mono results in an error CS0006: Metadata file Newtonsoft.Json.dll could not be found.
I already tried to add the following to the app.conf of my application, but that did not help. Also reinstalling the NuGet package did not help. Adding the Newtonsoft.Json.dll to the GAC does not work (fails with Failure adding assembly Newtonsoft.Json.dll to the cache: The file specified is not a valid assembly.). While trying around with the app.conf I observed the error message changed to error CS0009: Metadata file /opt/Newtonsoft.Json.dll does not contain valid metadata: Metadata file /opt/Newtonsoft.Json.dll does not contain valid metadata. That's why I guess he finds the dll but needs additional, valid meatadata. I thought about some sort of dll.conf.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
Does anyone have a hint on how to get this to work?
You have two possibilites:
Use latest Mono (6.6) from github. Compile it if package not avaliable.
Downgrade Newtonsoft.Json to version 11.0. Use binding redirect if nessecary.
Your code example works well on .NET 4.7, but since you're running Mono here are some possible solutions for you:
Compiler needs to know where to get this file.
If you say that you need to reference System.dll - compiler probably tries to find it in GAC (and it does find it).
When you reference unknown library like Newtonsoft.Json.dll it tries to search GAC and fails. Then it's probably trying to find it in working directory, etc..
Solution #1:
Try to set full path to your library;
Solution #2:
Try to register Newtonsoft.Json.dll in the GAC;
Solution #3:
Try .NET Core! It's amazing, cross-platform and 3.1 version now has open source WinForms and WPF!
I know that moving your code to .NET Core 3 takes time but still it's worth it.
I'm in the process of integrating a Xamarin Android project into our CI pipeline. We already use CakeBuild for other .NET projects and so I wanted to use it here, as well.
The problem is that I always get the following error message when trying to build with Cake:
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(406,2): error : Could not load assembly
'mscorlib, Version=0.0.0.0, Culture=neutral, PublicKeyToken='. Perhaps it doesn't exist in the Mono for Android profile? [C:\[myproject].csproj]
Building works in Visual Studio 2015 and using the Visual Studio Developer Command Prompt. Because of this, I was thinking it had something to do with the environment variables that are set in VS and via the VS command prompt. So what I did was make a small batch file:
call "%vs140comntools%vsvars32.bat"
Powershell.exe ./build.ps1 -Target Build
But I'm getting the exact same error. In my projects, there is no explicit reference to mscorlib.
The Cake build task looks like this:
Task("Build")
.IsDependentOn("Restore-NuGet-Packages")
.Does(() =>
{
var settings = new MSBuildSettings()
{
ArgumentCustomization = args =>
{
args = args.Append("/t:PackageForAndroid");
args = args.Append("/p:TargetFrameworkRootPath=\"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\"");
return args;
},
Verbosity = Verbosity.Normal
};
settings.SetConfiguration(configuration);
MSBuild("../myproject.csproj", settings);
});
I had to add the TargetFrameworkRootPath because it won't find the reference assemblies if I do not set it explicitly.
I'm wondering what else to do to replicate the build environment of VS / VS command prompt.
Are you targeting .NET Standard or is this still using PCL?
What does the verbose output look like? It should give you the exact MSBuild command being executed.
call "%vs140comntools%vsvars32.bat"
Powershell.exe ./build.ps1 -Target Build -Verbosity Diagnostic
I'm trying to automate builds using the MSBuild API - "BuildManager".
The following code works fine for building solutions/projects but fails when it comes to publishing.
The project publishes just fine when using the Visual Studio Publish page.
var collection = new ProjectCollection();
var parameters = new BuildParameters(collection);
parameters.Loggers = new List<ILogger> { Logger };
parameters.MaxNodeCount = Environment.ProcessorCount; //maxcpucount
var globalProperties = new Dictionary<string, string>();
globalProperties.Add("Configuration", "Debug");
globalProperties.Add("Platform", "AnyCPU");
globalProperties.Add("OutDir", binPath);
globalProperties.Add("OutputPath", publishPath);
globalProperties.Add("ApplicationVersion", version.ToString());
globalProperties.Add("GenerateBootstrapperSdkPath", #"C:\Program Files (x86)\Microsoft SDKs\ClickOnce Bootstrapper\");
//Doesn't work!
globalProperties.Add("SignToolPath", #"C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe");
BuildManager.DefaultBuildManager.ResetCaches();
var buildRequest = new BuildRequestData(projectFile.FileInfo.FullName, globalProperties, "4.0", new[] { "Rebuild", "Publish" }, null);
var buildResult = BuildManager.DefaultBuildManager.Build(parameters, buildRequest);
If I run this code, it fails with the following error:
An error occurred while signing: SignTool.exe not found.
As you can see I'm adding the global property called "GenerateBootstrapperSdkPath", which if its not there leads to this error:
Could not find required file 'setup.bin' in
'C:\PathToProject\Engine'.
This seems to be a vicious cycle, as soon as I specify a path for the bootstrapper, it can't find the SignTool.exe, if I don't it can't find the setup.bin.
Unfortunately the global property "SignToolPath" doesn't seem to do anything.
Any Ideas?
There was an old problem of locating bootstrapper by MSBuild which could be solved by creating registry key:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\GenericBootstrapper\4.0]
#="0"
"Path"="C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Bootstrapper\\"
Just set it to your SDK version and try again. Or perhaps use the path to your bootstrapper in BuildManager code based on the above one instead of:
C:\Program Files (x86)\Microsoft SDKs\ClickOnce Bootstrapper\
According to one of old blog entries the following registry values are resolved in search for the bootstrapper path and finally your local project folder under the Engine sub folder is checked and when not found MSBuild throws MSB3147 error:
HKLM\Software\Microsoft\GenericBootstrapper\<.NET Tools Version>\
HKLM \Software\Microsoft.NetFramework\SDKInstallRoot\Bootstrapper
HKLM \Software\Microsoft\VisualStudio\\InstallDir\Bootstrapper
Team build for ClickOnce application with bootstrapper
I understand from your description that finding solution to bootstrapper location would solve your problem since in that configuration you did not observe any SignTool.exe problems.
I migrate my project to .NET Core and some things work unexpectedly:
For example - i adding package "Npgsql": "3.1.0-alpha6" and write simple
public class Program
{
public static void Main(string[] args)
{
using (var pgConnection = new NpgsqlConnection("Server=localhost;Port=5432;Database=*;User Id=*;Password=*;"))
{
pgConnection.Open();
string sql = #"SELECT COUNT(*) FROM blog.posts";
var cmd = new NpgsqlCommand(sql, pgConnection);
var res = cmd.ExecuteScalar();
Console.WriteLine(res);
}
Console.Read();
}
}
It run OK with Debug run in Visual Studio with dnx-rc1-final.
But when I publish it - it can't run, because
System.IO.FileNotFoundException: Could not load file or assembly 'System.Net.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
This package used by Npgsql and when I try to generate outputs for assembly and try to compile into nuget packages - it's not working.
Why Debug run in Visual Studio find references on System.Net.Security, Version=4.0.0.0 and why published code can't do it ?
Need add previous version of packages:
"System.Net.Security": "4.0.0-beta-23225",
"System.Net.NetworkInformation": "4.1.0-beta-23225"
You have to copy the System.Net.Security dll into the Publish directory. You can copy it from the Debug directory.
Then it should work.
Both directories ar under ...\YourProject\bin\ folder
I'm using VS2012 and I want to build a .sln file programatically using c#. I understand I need to use the Microsoft.Build api to do so. I've gotten as far as building the solution
string slnPath= #"C:\Path\To\solution.sln";
ProjectCollection pc = new ProjectCollection();
List<ILogger> loggers = new List<ILogger>();
loggers.Add(new ConsoleLogger());
Dictionary<string, string> GlobalProperty = new Dictionary<string, string>();
GlobalProperty.Add("Configuration", "Debug");
GlobalProperty.Add("Platform", "Win32");
BuildRequestData BuildRequest = new BuildRequestData(projectFileName, GlobalProperty, "4.0", new string[] { "Build" }, null);
BuildParameters bp = new BuildParameters(pc);
bp.Loggers = loggers;
BuildResult buildResult = BuildManager.DefaultBuildManager.Build(bp, BuildRequest);
this executes the build command, but I get an error saying:
error MSB4019: The imported project "C:\Microsoft.Cpp.Default.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
Inside the .vcxproj the line that gives the error is:
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
I've tried setting the Environment Variable VCTargetsPath to be
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\
But I then get an error:
error MSB4127: The "SetEnv" task could not be instantiated from the assembly "C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.Build.CppTasks.Common.dll". Please verify the task assembly has been built using the same version of the Microsoft.Build.Framework assembly as the one installed on your computer and that your host application is not missing a binding redirect for Micros
oft.Build.Framework.
Does anyone have any suggestions as to how I can fix this?
EDIT: I see this appears to be a bug in Visual studio, but I can't reproduce the issue mentioned in the comment. If run a Developer command prompt, I can build solutions using MSBuild.