after Microsoft marked the BuildEngine.Engine and BuildEngine.Project as obsolete i have tried to use the new proposal from Microsoft how you can see it underneath. But i have no idea where i can integrate the xmlprojectfile. Is here someone who knows the solution of this problem?
The XML project file content
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ProjectToBuild Include ="myproject.csproj" />
</ItemGroup>
<Target Name="Build">
<MSBuild Projects="#(ProjectToBuild)"
Properties="Configuration=Debug" StopOnFirstFailure="true" />
</Target>
</Project>
The old and working version (but obsolete)
Microsoft.Build.BuildEngine.Engine engine = new Microsoft.Build.BuildEngine.Engine();
engine.DefaultToolsVersion = "4.0";
engine.RegisterLogger(new ConsoleLogger());
Microsoft.Build.BuildEngine.Project project = new Microsoft.Build.BuildEngine.Project(engine);
project.Load(xmlprojectfile);
if (!project.Build())
{
Console.ReadLine();
}
The new not working verison
Microsoft.Build.Evaluation.ProjectCollection collection = new Microsoft.Build.Evaluation.ProjectCollection();
collection.DefaultToolsVersion = "4.0";
collection.RegisterLogger(new ConsoleLogger());
Microsoft.Build.Evaluation.Project project = new Microsoft.Build.Evaluation.Project(collection);
if (!project.Build())
{
Console.ReadLine();
}
You also need to create a Microsoft.Build.Execution.BuildRequestData object containing the XML project file and a dictionary of std properties like Configuration and Platform. Then you create a Microsoft.Build.Execution.BuildParameters object containing your ProjectCollection object from your code snippet and pass that off to the default Microsoft.Build.Execution.BuildManager.
powershell pseudo code:
#set build properties
$props = new-object "System.Collections.Generic.Dictionary``2[[System.String],[System.String]]"
$props.Add("Configuration",$config)
$props.Add("Platform",$platform)
#create the projectCollection
$projectCollection = new-object Microsoft.Build.Evaluation.ProjectCollection -argumentList $props,$loggers,"ConfigurationFile,Registry"
$request = new-object Microsoft.Build.Execution.BuildRequestData -argumentlist $project,$props,$null,$targets,$null
#create a BuildParameters object to hold the Project Collection
$parameters = new-object Microsoft.Build.Execution.BuildParameters -argumentlist #($projectCollection)
$parameters.MaxNodeCount = 1
$parameters.Loggers = $projectCollection.Loggers
$parameters.ToolsetDefinitionLocations = "ConfigurationFile,Registry"
$parameters.DefaultToolsVersion = $toolsVersion
#get the build manager and submit a build request with the appropriate parameters
$manager = [Microsoft.Build.Execution.BuildManager]::DefaultBuildManager
$result = $manager.Build($parameters, $request)
You are missing project.Load(xmlprojectfile); line in your migrated code. You have to add xmlprojectfile into projectcollection somehow, I guess.
Instead of creating a new Project with new keyword:
// var project = new Project(collection);
Use this:
var project = collection.LoadProject("myproject.csproj")
Related
My goal is to test this code to make sure that Stanford Core NLP installed properly.
First I installed StanfordCOreNLP package using NuGet package manager and then I downloaded a zip file that contained a jar file that needed to be installed using jar -xf command , and then I ran the code.
At (var pipeline = new StanfordCoreNLP(props);)
I'm getting an error that says:
edu.stanford.nlp.io.RuntimeIOException: Error while loading a tagger model(probably missing model file)"
Inner Exception IOException:Unable to open"edu/stanford/nlp/models/pos-tagger/english-left3words/english-left3words-distsim.tagger" as class path, filename or URL
var jarRoot = #"D:/VisualStudioProjects/C#MachineLearningProjects/Chapter3TwiterSentiment/CoreNLPTest2/CoreNLPTest2/edu/stanford/nlp/models/pos-tagger";
var text = "We're going to test our CoreNLP instalation!!";
Properties props = new Properties();
props.setProperty("annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref");
props.setProperty("ner.useSUTime", "0");
var curDir = Environment.CurrentDirectory;
Directory.SetCurrentDirectory(jarRoot);
var pipeline = new StanfordCoreNLP(props);
Directory.SetCurrentDirectory(curDir);
var annotation = new Annotation(text);
pipeline.annotate(annotation);
using (var stream = new ByteArrayOutputStream())
{
pipeline.prettyPrint(annotation, new PrintWriter(stream));
Console.WriteLine(stream.toString());
stream.close();
}
Console.ReadKey();
Please follow the below steps:
Step 1: Download Core NLP
Step 2: Unzip d:\stanford-corenlp-full-2018-10-05
Step 3: Unzip d:\stanford-corenlp-full-2018-10-05\stanford-corenlp-3.9.2-models.jar
Step 4: Change var jarRoot = #"d:/stanford-corenlp-full-2018-10-05/stanford-corenlp-3.9.2-models";
Step 5: Change props.setProperty("ner.useSUTime", "0"); to props.setProperty("sutime.binders", "0")
I have been trying to write an MsBuild task to automatically get Nuget packages from a feed url and automatically update the packages.config to update to the latest version.
// ---- Download and install a package at a desired path ----
var sourceUri = new Uri("FEED URL");
// ---- Update the ‘packages.config’ file ----
var packageReferenceFile = new PackageReferenceFile("../../packages.config");
string packagesPath = "../../packages";
IPackageRepository sourceRepository = PackageRepositoryFactory.Default.CreateRepository(sourceUri.ToString());
PackageManager packageManager = new PackageManager(sourceRepository, packagesPath);
foreach (var sourcePackage in sourceRepository.GetPackages().Where(x => x.IsLatestVersion))
{
if (!packageReferenceFile.EntryExists(sourcePackage.Id + " " + sourcePackage.Version, sourcePackage.Version))
{
var oldPackage = packageReferenceFile.GetPackageReferences().FirstOrDefault(x => x.Id.Contains(sourcePackage.Id));
if (oldPackage != null)
{
packageReferenceFile.DeleteEntry(oldPackage.Id, oldPackage.Version);
}
packageManager.InstallPackage(sourcePackage.Id, SemanticVersion.Parse(sourcePackage.Version.ToFullString()));
// Get the target framework of the current project to add --> targetframework="net452" attribute in the package.config file
var currentTargetFw = Assembly.GetExecutingAssembly()
.GetCustomAttributes(typeof(TargetFrameworkAttribute), false);
var targetFrameworkAttribute = ((TargetFrameworkAttribute[]) currentTargetFw).FirstOrDefault();
// Update the packages.config file
packageReferenceFile.AddEntry(sourcePackage.GetFullName(),
SemanticVersion.Parse(sourcePackage.Version.ToFullString()), false,
new FrameworkName(targetFrameworkAttribute.FrameworkName));
}
}
This is working fine as a console app and is automatically reading the file correctly and updating the necessary references.
When i try to run this as an MsBuild task I keep running into errors.
An error has occurred during compilation. c:\Users\user\AppData\Local\Temp\dkkg20ya.0.cs(22,11) : error CS0246: The type or namespace name 'NuGet' could not be found (are you missing a using directive or an assembly reference?)
The task factory "CodeTaskFactory" could not be loaded from the assembly "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Build.Tasks.v15.0.dll". The task factory must return a value for the "TaskType" property.
This is the code I have put in the csproj (also moved to the nuget.targets to test)
<Target Name="BeforeBeforeBuild" BeforeTargets="BeforeBuild">
<UpdateNugetFiles />
</Target>
<UsingTask TaskName="UpdateNugetFiles" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v$(MSBuildToolsVersion).dll" >
<Task>
<Reference Include="System.Core" />
<Using Namespace="System" />
<Using Namespace="System.Linq" />
<Using Namespace="System.Reflection" />
<Using Namespace="System.Runtime.Versioning" />
<Using Namespace="NuGet" />
<Code Type="Fragment" Language="cs">
<![CDATA[
try {
// ---- Download and install a package at a desired path ----
var sourceUri = new Uri("FEED URL");
// ---- Update the ‘packages.config’ file ----
var packageReferenceFile = new PackageReferenceFile("../../packages.config");
string packagesPath = "../../packages";
IPackageRepository sourceRepository = PackageRepositoryFactory.Default.CreateRepository(sourceUri.ToString());
PackageManager packageManager = new PackageManager(sourceRepository, packagesPath);
foreach (var sourcePackage in sourceRepository.GetPackages().Where(x => x.IsLatestVersion))
{
if (!packageReferenceFile.EntryExists(sourcePackage.Id + " " + sourcePackage.Version, sourcePackage.Version))
{
var oldPackage = packageReferenceFile.GetPackageReferences().FirstOrDefault(x => x.Id.Contains(sourcePackage.Id));
if (oldPackage != null)
{
packageReferenceFile.DeleteEntry(oldPackage.Id, oldPackage.Version);
}
packageManager.InstallPackage(sourcePackage.Id, SemanticVersion.Parse(sourcePackage.Version.ToFullString()));
// Get the target framework of the current project to add targetframework="net452" attribute in the package.config file
currentTargetFw = Assembly.GetExecutingAssembly()
.GetCustomAttributes(typeof(TargetFrameworkAttribute), false);
var targetFrameworkAttribute = ((TargetFrameworkAttribute[]) currentTargetFw).FirstOrDefault();
// Update the packages.config file
packageReferenceFile.AddEntry(sourcePackage.GetFullName(),
SemanticVersion.Parse(sourcePackage.Version.ToFullString()), false,
new FrameworkName(targetFrameworkAttribute.FrameworkName));
}
}
return true;
}
catch (Exception ex) {
Log.LogErrorFromException(ex);
return false;
}
]]>
</Code>
</Task>
</UsingTask>
Any ideas on how to resolve this as cannot seem to find a solution.
Overall what to run this a pre step on a CI build to keep nugets up to date.
Thanks
Tim
Just call
nuget restore "your_solution.sln"
Don't reinvent the wheel by writing it in C# code.
Nuget Update Packages.config in MSBuild BeforeBuild Step
Not sure where your code issue comes from. It may be simpler just use NuGet.exe to restore and update the solution instead of trying to use C# code.
So you could add following nuget command line in the MSBuild BeforeBuild Step
<Target Name="BeforeBeforeBuild" BeforeTargets="BeforeBuild">
<Exec Command="$(YourNuGetPath)\nuget.exe restore "$(YouSolutionPath)\YourSolution.sln" -PackagesDirectory "$(YouPackagePath)\packages"" />
<Exec Command="$(YourNuGetPath)\nuget.exe update "$(YouSolutionPath)\YourSolution.sln"" />
</Target>
Note: If you are using Visual Studio, Visual Studio will automatically check the missing packages during the build and restore them: Package Restore.
Hope this helps.
I installed the three following packages into my console application:
Microsoft.Build
Microsoft.Build.Framework
Microsoft.Build.Tasks.Core
Microsoft.Build.Utilities.Core
And I tried to use the following method to build a project:
static void Build(string projectPath)
{
var logger = new ConsoleLogger(LoggerVerbosity.Normal);
logger.ShowSummary = true;
var manager = BuildManager.DefaultBuildManager;
var projectInstance = new ProjectInstance(projectPath);
var result = manager.Build(
new BuildParameters()
{
DetailedSummary = true,
Loggers = new List<ILogger>() { logger }
},
new BuildRequestData(projectInstance, new string[] { "Build" }));
var buildResult = result.ResultsByTarget["Build"];
var buildResultItems = buildResult.Items;
}
However, after I ran the code, I got the error that described in the following image:
Why is this happening and how can I fix it?
I think you're not using tht right MSBuild version. Try to set the variable explicitly in your .proj :
<MSBuildExtensionsPath>C:\Program Files (x86)\MSBuild</MSBuildExtensionsPath>
It seems the best solution is to use MSBuild command line in Process class. A working sample is as follows:
var buildOutput = new List<string>();
var buildError = new List<string>();
var buildProcess = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\MSBuild\\15.0\\Bin\\MSBuild.exe",
Arguments = projectPath + " /t:Rebuild /p:Configuration=Debug",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
buildProcess.Start();
while (!buildProcess.StandardOutput.EndOfStream)
{
buildOutput.Add(buildProcess.StandardOutput.ReadLine());
}
while (!buildProcess.StandardError.EndOfStream)
{
buildError.Add(buildProcess.StandardError.ReadLine());
}
And then you could use the output to determine whether the build was successful or not. The important note is that you have to find the correct path of MSBuild.exe file as there are several versions of this file and in my case (VS 2017) the correct path is the one in the sample code.
One of BuildRequestData constructor overloads supports a parameter called "toolVersion". Since you are using Visual Studio 2017, set it as "15.0".
EDIT: I quitted using the .Net Framework provided MSBuild version (the one located here):
System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
C:\Windows\Microsoft.NET\Framework\v4.0.30319
Instead, I'm using the one located here:
C:\Program Files (x86)\MSBuild\{version}\Bin
This version provide extra parameters as LangVersion or DeployOnBuild.
We have created solution like the one below and added the default project after creating solution. Please refer code below
Type visualStudioType = Type.GetTypeFromProgID("VisualStudio.DTE.12.0", true);
DTE env = Activator.CreateInstance(visualStudioType, true) as DTE;
ServiceProvider serviceProvider = new ServiceProvider(env as Microsoft.VisualStudio.OLE.Interop.IServiceProvider);
DTE dte = (DTE)serviceProvider.GetService(typeof(DTE));
Object obj = System.Activator.CreateInstance(visualStudioType, true);
EnvDTE80.DTE2 dte8Obj = (EnvDTE80.DTE2)obj;
Solution2 soln = (Solution2)dte8Obj.Solution;
1.I get exception like below, When create project solution.
2.After create project, We cannot able to convert project as VSProject. Its showing exception like below.
Please give solution for resolve above mention issues .
Your code can be simplified to:
Type visualStudioType = Type.GetTypeFromProgID("VisualStudio.DTE.12.0", true);
EnvDTE80.DTE2 dte2 = Activator.CreateInstance(visualStudioType, true) as EnvDTE80.DTE2;
EnvDTE80.Solution2 soln = dte2.Solution as EnvDTE80.Solution2;
Regarding the error locating EnvDTE version 7.0.3300.0 see:
Error When EnvDTE Is Used with VSLangProj Assemblies
While there are many other topics that provide great information on the topic posted here already, I've not yet been able to find the answer to my dilemma.
While I'm somewhat competent with PowerShell, I am completely new with C#/VisualStudio. I have some PowerShell code that consumes a Web service that works perfectly well:
function Modify-SPMLObject() {
param(
[string]$Uri
, [string]$ObjectDN
, [PSCredential]$Creds
, [hashtable]$Attributes
)
$MyService = New-WebServiceProxy -Uri $Uri -Credential $Creds
$Type = $MyService.GetType().Namespace
$ModifyRequest = New-Object -TypeName ($Type + ".CModifyRequest")
$CPSOID = New-Object -TypeName ($Type + ".CPSOID")
$CPSOID.ID = $ObjectDN
$ModifyRequest.psoID = $CPSOID
$Modifications = #()
foreach ($Attribute in $Attributes.Keys) {
$Modification = New-Object -TypeName ($Type + ".modification")
$Modification.Name = $Attribute
$Modification.Value = $Attributes.$Attribute
$Modification.Operation = "replace"
$Modifications += $Modification
}
$ModifyRequest.modification = $Modifications
$MyService.modify($ModifyRequest)
}
My challenge is converting this to C# in VisualStudio. In lieu of the call to New-WebServiceProxy, I've included a reference in my project to the Web service. The reference is named MyService. Hence, the code I've created thus far:
var ModifyRequest = new MyService.CModifyRequest();
var CPSOID = new MyService.CPSOID();
CPSOID.ID = "a hard-coded value for now";
ModifyRequest.psoID = CPSOID;
var modifications = new MyService.modification[1];
var modification = new MyService.modification();
modification.name = "another hard-coded value for the moment";
modification.operation = "replace";
modification.value = new string[1] { "This is a test" };
modifications[0] = modification;
ModifyRequest.modification = modifications;
The one thing that I haven't been able to figure out, however, is how, in C#, to accomplish the task that the PowerShell version accomplishes thus:
$MyService.modify($ModifyRequest)
In VS, if I try to call:
MyService.modify(ModifyRequest);
I get the message
Error CS0234 The type or namespace name 'modify' does not exist in the namespace 'WebApplication2.MyService' (are you missing an assembly reference?)
Any tips are most appreciated!
EDIT: Found the solution. In answer to LachlanB, typing "MyService" provided a list of methods and classes - but not the modify operation that I was seeking and defined in the WSDL thus:
<wsdl:operation name="modify">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Changes the specified object on the target.</wsdl:documentation>
<wsdl:input message="tns:modifySoapIn"/>
<wsdl:output message="tns:modifySoapOut"/>
</wsdl:operation>
What I needed to include was, first, the reference:
using WebApplication2.MyService;
With that, I could then call:
MyApplicationClassName webService = new MyApplicationClassName();
CModifyResponse response = webService.modify(ModifyRequest);
where "MyApplicationClassName" was automatically generated as was listed in References.cs in the following statement:
public partial class MyApplicationClassName : System.Web.Services.Protocols.SoapHttpClientProtocol {
Thanks to those that tried to help!