21 public const string DefaultMSBuildVersion =
"15.0";
25 if (PlayerSettings.GetScriptingBackend(BuildTargetGroup.WSA) == ScriptingImplementation.IL2CPP && IsIl2CppAvailable())
30 return PlayerSettings.GetScriptingBackend(BuildTargetGroup.WSA) == ScriptingImplementation.WinRTDotNET && IsDotNetAvailable();
35 return Directory.Exists(EditorApplication.applicationContentsPath +
"\\PlaybackEngines\\MetroSupport\\Managed\\UAP");
40 return Directory.Exists(EditorApplication.applicationContentsPath +
"\\PlaybackEngines\\MetroSupport\\Managed\\il2cpp");
49 if (EditorBuildSettings.scenes.Length == 0)
51 return EditorUtility.DisplayDialog(
"Attention!",
52 "No scenes are present in the build settings!\n\n Do you want to cancel and add one?",
53 "Continue Anyway",
"Cancel Build");
67 public static bool BuildSLN(
string buildDirectory,
bool showDialog =
true)
70 bool buildSuccess =
false;
72 if (CheckBuildScenes() ==
false)
80 OutputDirectory = buildDirectory,
81 Scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(scene => scene.path),
82 BuildTarget = BuildTarget.WSAPlayer,
84 WSAUWPBuildType = EditorUserBuildSettings.wsaUWPBuildType,
85 WSAUwpSdk = EditorUserBuildSettings.wsaUWPSDK,
88 #if UNITY_2018_1_OR_NEWER 89 PostBuildAction = (innerBuildInfo, buildReport) =>
91 if (buildReport.summary.result !=
UnityEditor.Build.Reporting.BuildResult.Succeeded)
93 EditorUtility.DisplayDialog(
string.Format(
"{0} WindowsStoreApp Build {1}!", PlayerSettings.productName, buildReport.summary.result),
"See console for details",
"OK");
96 PostBuildAction = (innerBuildInfo, buildError) =>
98 if (!
string.IsNullOrEmpty(buildError))
100 EditorUtility.DisplayDialog(
string.Format(
"{0} WindowsStoreApp Build Failed!", PlayerSettings.productName), buildError,
"OK");
107 if (!EditorUtility.DisplayDialog(PlayerSettings.productName,
"Build Complete",
"OK",
"Build AppX"))
110 PlayerSettings.productName,
134 if (msBuildVersion.Equals(
"14.0"))
136 using (RegistryKey key =
137 Registry.LocalMachine.OpenSubKey(
138 string.Format(
@"Software\Microsoft\MSBuild\ToolsVersions\{0}", msBuildVersion)))
142 var msBuildBinFolder = (string)key.GetValue(
"MSBuildToolsPath");
143 return Path.Combine(msBuildBinFolder,
"msbuild.exe");
149 msBuildVersion =
"15.0";
152 string output =
@"/C vswhere -version " + msBuildVersion +
" -products * -requires Microsoft.Component.MSBuild -property installationPath";
155 string programFiles =
@"C:\Program Files (x86)\Microsoft Visual Studio\Installer";
157 var vswherePInfo =
new ProcessStartInfo
159 FileName =
"cmd.exe",
160 CreateNoWindow =
true,
161 UseShellExecute =
false,
162 RedirectStandardOutput =
true,
163 RedirectStandardError =
false,
165 WorkingDirectory = programFiles
168 using (var vswhereP =
new Process())
170 vswhereP.StartInfo = vswherePInfo;
172 output = vswhereP.StandardOutput.ReadToEnd();
173 vswhereP.WaitForExit();
176 string[] paths = output.Split(
new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
178 if (paths.Length > 0)
182 string bestPath = paths.OrderBy(p => p.ToLower().Contains(
"enterprise"))
183 .ThenBy(p => p.ToLower().Contains(
"professional"))
184 .ThenBy(p => p.ToLower().Contains(
"community")).First();
186 return bestPath +
@"\MSBuild\" + msBuildVersion +
@"\Bin\MSBuild.exe";
189 Debug.LogError(
"Unable to find a valid path to Visual Studio Instance!");
195 Debug.Assert(File.Exists(nugetPath));
196 Debug.Assert(Directory.Exists(storePath));
198 var nugetPInfo =
new ProcessStartInfo
200 FileName = nugetPath,
201 CreateNoWindow =
true,
202 UseShellExecute =
false,
203 Arguments =
"restore \"" + storePath +
"/project.json\"" 206 using (var nugetP =
new Process())
208 nugetP.StartInfo = nugetPInfo;
210 nugetP.WaitForExit();
215 return File.Exists(storePath +
"\\project.lock.json");
218 public static bool BuildAppxFromSLN(
string productName,
string msBuildVersion,
bool forceRebuildAppx,
string buildConfig,
string buildPlatform,
string buildDirectory,
bool incrementVersion,
bool showDialog =
true)
220 EditorUtility.DisplayProgressBar(
"Build AppX",
"Building AppX Package...", 0);
221 string slnFilename = Path.Combine(buildDirectory, PlayerSettings.productName +
".sln");
223 if (!File.Exists(slnFilename))
225 Debug.LogError(
"Unable to find Solution to build from!");
226 EditorUtility.ClearProgressBar();
231 var msBuildPath = CalcMSBuildPath(msBuildVersion);
233 if (!File.Exists(msBuildPath))
235 Debug.LogErrorFormat(
"MSBuild.exe is missing or invalid:\n{0}.", msBuildPath);
236 EditorUtility.ClearProgressBar();
241 string unity = Path.GetDirectoryName(EditorApplication.applicationPath);
242 System.Diagnostics.Debug.Assert(unity != null,
"unity != null");
243 string storePath = Path.GetFullPath(Path.Combine(Path.Combine(Application.dataPath,
".."), buildDirectory));
244 string solutionProjectPath = Path.GetFullPath(Path.Combine(storePath, productName +
@".sln"));
247 if (!File.Exists(storePath +
"\\project.json"))
249 File.Copy(unity +
@"\Data\PlaybackEngines\MetroSupport\Tools\project.json", storePath +
"\\project.json");
252 string assemblyCSharp =
string.Format(
"{0}/GeneratedProjects/UWP/Assembly-CSharp", storePath);
253 string assemblyCSharpFirstPass =
string.Format(
"{0}/GeneratedProjects/UWP/Assembly-CSharp-firstpass", storePath);
254 bool restoreFirstPass = Directory.Exists(assemblyCSharpFirstPass);
255 string nugetPath = Path.Combine(unity,
@"Data\PlaybackEngines\MetroSupport\Tools\NuGet.exe");
258 if (PlayerSettings.GetScriptingBackend(BuildTargetGroup.WSA) == ScriptingImplementation.WinRTDotNET &&
259 (!RestoreNugetPackages(nugetPath, storePath) ||
260 !RestoreNugetPackages(nugetPath, storePath +
"\\" + productName) ||
261 EditorUserBuildSettings.wsaGenerateReferenceProjects && !RestoreNugetPackages(nugetPath, assemblyCSharp) ||
262 EditorUserBuildSettings.wsaGenerateReferenceProjects && restoreFirstPass && !RestoreNugetPackages(nugetPath, assemblyCSharpFirstPass)))
264 Debug.LogError(
"Failed to restore nuget packages");
265 EditorUtility.ClearProgressBar();
269 EditorUtility.DisplayProgressBar(
"Build AppX",
"Building AppX Package...", 25);
272 if (!SetPackageVersion(incrementVersion))
274 Debug.LogError(
"Failed to increment package version!");
275 EditorUtility.ClearProgressBar();
280 var pInfo =
new ProcessStartInfo
282 FileName = msBuildPath,
283 CreateNoWindow =
true,
284 UseShellExecute =
false,
285 RedirectStandardOutput =
true,
286 RedirectStandardError =
true,
287 Arguments =
string.Format(
"\"{0}\" /t:{1} /p:Configuration={2} /p:Platform={3} /verbosity:m",
289 forceRebuildAppx ?
"Rebuild" :
"Build",
294 var process =
new Process
297 EnableRaisingEvents =
true 302 process.ErrorDataReceived += (sender, args) =>
304 if (!
string.IsNullOrEmpty(args.Data))
306 Debug.LogError(args.Data);
310 process.OutputDataReceived += (sender, args) =>
312 if (!
string.IsNullOrEmpty(args.Data))
314 Debug.Log(args.Data);
318 if (!process.Start())
320 Debug.LogError(
"Failed to start process!");
321 EditorUtility.ClearProgressBar();
327 process.BeginOutputReadLine();
328 process.BeginErrorReadLine();
329 process.WaitForExit();
331 EditorUtility.ClearProgressBar();
333 if (process.ExitCode == 0 && showDialog &&
334 !EditorUtility.DisplayDialog(
"Build AppX",
"AppX Build Successful!",
"OK",
"Open AppX Folder"))
336 Process.Start(
"explorer.exe",
string.Format(
"/f /open,{0}/{1}/AppPackages", Path.GetFullPath(
BuildDeployPrefs.
BuildDirectory), PlayerSettings.productName));
339 if (process.ExitCode != 0)
341 Debug.LogError(
string.Format(
"MSBuild error (code = {0})", process.ExitCode));
342 EditorUtility.ClearProgressBar();
343 EditorUtility.DisplayDialog(PlayerSettings.productName +
" build Failed!",
"Failed to build appx from solution. Error code: " + process.ExitCode,
"OK");
357 Debug.LogError(
"Cmd Process EXCEPTION: " + e);
358 EditorUtility.ClearProgressBar();
365 private static bool SetPackageVersion(
bool increment)
370 if (manifests.Length == 0)
376 string manifest = manifests[0];
377 var rootNode = XElement.Load(manifest);
378 var identityNode = rootNode.Element(rootNode.GetDefaultNamespace() +
"Identity");
380 if (identityNode == null)
389 var versionAttr = identityNode.Attribute(XName.Get(
"Version"));
391 if (versionAttr == null)
401 var version = PlayerSettings.WSA.packageVersion;
402 var newVersion =
new Version(version.Major, version.Minor, increment ? version.Build + 1 : version.Build, version.Revision);
404 PlayerSettings.WSA.packageVersion = newVersion;
405 versionAttr.Value = newVersion.ToString();
406 rootNode.Save(manifest);