由於自己項目需要,但是之前對於這塊完全沒有經驗,各種百度和bing,花了幾個小時才勉強搞定。
本來想用CSharpCodeProvider的但是不知道能不能編譯xaml.,於是直接用msbuild
我的電腦裏的msbuild的版本好像是4.0,之前運行各種提示我ToolsVersion是15.0但是最大隻能是4.0. 花了好久通過bing才知道
原來最新的msbuild需要通過nuget安裝..
於是..注意右邊的版本號
安裝好之後,大致上只需要添加這些引用
using Microsoft.Build.Evaluation;
using Microsoft.Build.Framework;
using Microsoft.Build.Logging;
using System;
using System.Collections.Generic;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Framework;
using Microsoft.Build.Logging;
using System;
using System.Collections.Generic;
static class Program
{
static void Main(string[] args)
{
//項目集合
ProjectCollection collection = new ProjectCollection();
//csproj文件路徑
string projectFileName = @"f:\Projects\CSharp\CsyGame\CsyGame\Game.Runtime.csproj";
//加載一個項目 也可以直接Project project =new Project(projectFileName)
Project project = collection.LoadProject(projectFileName);
//創建一個新的實例,
//project.CreateProjectInstance();
//重新評估,用於刷新,比如設置輸出目錄之後
//project.ReevaluateIfNecessary();
//項目集合設置爲release模式
collection.SetGlobalProperty("Configuration", "Release");
//這個應該是單獨設置工程的編譯模式
//project.SetProperty("Configuration", "Release");
//裏面很多屬性,比如輸出目錄,輸出的類型(dll,exe)都可以設置 project.SetProperty()就可以
//project.Properties;
//logger 可以顯示編譯的過程 有好多.都位於Microsoft.Build.Logging,比如FileLogger...
//這個是打印到控制檯
ConsoleLogger logger = new ConsoleLogger();
List<ILogger> loggers = new List<ILogger>
{
//添加
logger
};
try
{
//開始編譯,有個返回值返回成功或者失敗
//第一個參數是target,可以有多個target,調試的時候看project.targets就知道了
// 也可以不填 project.Build(loggers);
//Rebuild 表示重新生成,跟vs裏是一樣的
project.Build("Rebuild",loggers);
}
finally
{
}
collection.Dispose();
Console.ReadKey(true);
}
}
輸出結果 0 warnings 0 errors
ProjectItem
//獲取所有需要編譯的文件
var NewCompile = project.GetItems("Compile");
//獲取所有dll引用
var NewReference = project.GetItems("Reference");
//獲取項目引用(比如你的項目引用了你的另一個項目就可以獲取到)
var NewProjectReference = project.GetItems("ProjectReference");
//如果有項目引用但是編譯失敗的話
//我的解決辦法是獲取引用的csproj文件,再通過new Project("路徑") 加載,然後編譯它
//再獲取到編譯成功的dll,然後添加dll的絕對路徑(debug或者release下的dll)
//把引用的dll路徑添加到Reference下
//如果dll路徑爲空
if(string.IsNullOrEmpty(DllPath))
{
return;
}
//設置metadata
List<KeyValuePair<string, string>> refmetadata = new List<KeyValuePair<string, string>>
{
//只有一個 HintPath 這個key是固定(可以用notepad打開csproj文件看看),value就是dll的絕對路徑
new KeyValuePair<string, string>("HintPath", DllPath)
};
//添加item "Reference" 是固定的表示添加引用,"CsyApi"是dll程序集名字,
project.AddItem("Reference", "CsyApi", refmetadata);
//添加cs文件 "Compile"是固定的 RunningCsPath是cs文件的絕對路徑(也可以是相對路徑)
project.AddItem("Compile", RunningCsPath);
//移除一個item
//比如移除program.cs文件,在 Compile 裏,先獲取
var ProgramCsItem = project.GetItems("Compile").FirstOrDefault(item => item.EvaluatedInclude.Equals("Program.cs"));
//移除
project.RemoveItem(ProgramCsItem);
移除Property也是類似操作 但是是調用RemoveProperty函數
因爲我的項目需要編譯xaml,還需重定向
在app.config裏面,runtime 重定向 Microsoft.Build.Framework和Microsoft.Build
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="CsyGameEditor.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>