[setup-windows] Fix for VS 2017 and MSBuild 15+ (#811)

When building `HelloWorld.csproj`, my machine is loading reference
assemblies from:

    ReferenceAssemblyPaths: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v1.0\

This is different from what `setup-windows.exe` is making a link for. So
if I attempt to build `HelloWorld.csproj` for API 26 /
`$(TargetFrameworkVersion)` v8.0, it fails because the framework does not
exist on my system. It turns out this is happening because I am using
MSBuild 15.0 from my VS install, instead of the .NET framework version
of MSBuild.

The fix here is to create an additional file link for VS 2017 if
`VSINSTALLDIR` is set. I also streamlined the `Uninstall` method so
it takes in a list of directories.
This commit is contained in:
Jonathan Peppers 2017-09-05 15:01:27 -05:00 коммит произвёл Jonathan Pryor
Родитель 7ad9c59216
Коммит b05b5b6e61
2 изменённых файлов: 32 добавлений и 25 удалений

Просмотреть файл

@ -111,6 +111,7 @@ Administrator-elevated **Developer Command Prompt for VS 2017** window:
Within the elevated command prompt, execute the `setup-windows.exe` program:
> C:\xa-sdk\oss-xamarin.android_v7.4.99.60_Darwin-x86_64_master_4f3d604\bin\Debug\bin\setup-windows.exe
Executing: MKLINK /D "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid" "C:\xa-sdk\oss-xamarin.android_v7.4.99.57_Darwin-x86_64_master_97f08f7\bin\Debug\lib\xamarin.android\xbuild-frameworks\MonoAndroid"
Executing: MKLINK /D "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid" "C:\xa-sdk\oss-xamarin.android_v7.4.99.57_Darwin-x86_64_master_97f08f7\bin\Debug\lib\xamarin.android\xbuild-frameworks\MonoAndroid"
Executing: MKLINK /D "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android" "C:\xa-sdk\oss-xamarin.android_v7.4.99.57_Darwin-x86_64_master_97f08f7\bin\Debug\lib\xamarin.android\xbuild\Xamarin\Android"
Success!

Просмотреть файл

@ -31,14 +31,18 @@ namespace Xamarin.Android.Tools
var prefix = Path.GetDirectoryName (appDir);
var hash = XAZipFolderNameToHash (Path.GetFileName (Path.GetDirectoryName (Path.GetDirectoryName (prefix))));
var refAssembliesDirectories = new List<string> ();
var progFiles = Environment.GetEnvironmentVariable ("ProgramFiles(x86)");
var vsInstall = Environment.GetEnvironmentVariable ("VSINSTALLDIR");
if (string.IsNullOrEmpty (vsInstall)) {
vsInstall = progFiles;
} else {
refAssembliesDirectories.Add (Path.Combine (vsInstall, "Common7", "IDE", "ReferenceAssemblies", "Microsoft", "Framework", "MonoAndroid"));
}
refAssembliesDirectories.Add (Path.Combine (progFiles, "Reference Assemblies", "Microsoft", "Framework", "MonoAndroid"));
var msbuildTargets = Path.Combine (vsInstall, "MSBuild", "Xamarin", "Android");
var newTargets = Path.Combine (prefix, "lib", "xamarin.android", "xbuild", "Xamarin", "Android");
var refAssemblies = Path.Combine (progFiles, "Reference Assemblies", "Microsoft", "Framework", "MonoAndroid");
var newAssemblies = Path.Combine (prefix, "lib", "xamarin.android", "xbuild-frameworks", "MonoAndroid");
if (Path.DirectorySeparatorChar != '\\') {
@ -47,30 +51,36 @@ namespace Xamarin.Android.Tools
}
if (args.Length == 0 || args.Any (v => string.Equals (v, "install", StringComparison.OrdinalIgnoreCase) || string.Equals (v, "/install", StringComparison.OrdinalIgnoreCase))) {
return Install (msbuildTargets, newTargets, refAssemblies, newAssemblies, hash);
return Install (hash, msbuildTargets, newTargets, refAssembliesDirectories, newAssemblies);
}
if (args.Any (v => string.Equals (v, "uninstall", StringComparison.OrdinalIgnoreCase) || string.Equals (v, "/uninstall", StringComparison.OrdinalIgnoreCase))) {
return Uninstall (msbuildTargets, refAssemblies, hash);
var directories = new List<string> (refAssembliesDirectories);
directories.Add (msbuildTargets);
return Uninstall (hash, directories);
}
Console.Error.WriteLine ($"{AppName}: Invalid command `{string.Join (" ", args)}`.");
return 1;
}
static int Install (string msbuildTargets, string newTargets, string refAssemblies, string newAssemblies, string hash)
static int Install (string hash, string msbuildTargets, string newTargets, List<string> refAssembliesDirectories, string newAssemblies)
{
var backupAssemblies = GetNewBackupName (refAssemblies, hash);
var backupTargets = GetNewBackupName (msbuildTargets, hash);
try {
foreach (var refAssemblies in refAssembliesDirectories) {
var backupAssemblies = GetNewBackupName (refAssemblies, hash);
Directory.CreateDirectory (Path.GetDirectoryName (refAssemblies));
Directory.CreateDirectory (Path.GetDirectoryName (msbuildTargets));
if (!CreateSymbolicLink (refAssemblies, newAssemblies, backupAssemblies))
return 1;
}
var backupTargets = GetNewBackupName (msbuildTargets, hash);
Directory.CreateDirectory (Path.GetDirectoryName (msbuildTargets));
if (!CreateSymbolicLink (msbuildTargets, newTargets, backupTargets)) {
return 1;
}
if (CreateSymbolicLink (refAssemblies, newAssemblies, backupAssemblies) &&
CreateSymbolicLink (msbuildTargets, newTargets, backupTargets)) {
Console.WriteLine ("Success!");
return 0;
}
return 1;
}
catch (UnauthorizedAccessException e) {
Console.Error.WriteLine ($"{AppName}: {e.Message}");
Console.Error.WriteLine (e.ToString ());
@ -130,18 +140,14 @@ namespace Xamarin.Android.Tools
return true;
}
static int Uninstall (string msbuildTargets, string refAssemblies, string hash)
static int Uninstall (string hash, List<string> directories)
{
var backupTargets = GetExistingBackupName (msbuildTargets, hash);
var backupAssemblies = GetExistingBackupName (refAssemblies, hash);
Directory.Delete (msbuildTargets);
if (backupTargets != null && Directory.Exists (backupTargets)) {
Directory.Move (backupTargets, msbuildTargets);
foreach (var directory in directories) {
var backup = GetExistingBackupName (directory, hash);
Directory.Delete (directory);
if (backup != null && Directory.Exists (backup)) {
Directory.Move (backup, directory);
}
Directory.Delete (refAssemblies);
if (backupAssemblies != null && Directory.Exists (backupAssemblies)) {
Directory.Move (backupAssemblies, refAssemblies);
}
return 0;
}