Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3b39127
First implementation of Microsoft.Build.UnGAC. Workarounds galore!
benvillalobos Jul 30, 2020
ae20d69
comments
benvillalobos Jul 30, 2020
cbbd763
Added .swr file. Try catching the program to ensure it doesn't fail a…
benvillalobos Aug 4, 2020
b032a19
catching my own nits
benvillalobos Aug 4, 2020
46155cb
nits!
benvillalobos Aug 4, 2020
cacd72c
minor write update
benvillalobos Aug 7, 2020
93d9f78
Minor PR feedback
benvillalobos Aug 12, 2020
42a8bf5
Testing build without packageinternalrevision
benvillalobos Aug 12, 2020
3857ba1
Using unmanaged code.
benvillalobos Aug 19, 2020
3488360
Fixing build error with xunit.console
benvillalobos Aug 20, 2020
034d84d
Moved exe.swr to its own directory. Otherwise both .swr files are pas…
benvillalobos Aug 26, 2020
13042b8
Transitioning UnGAC.Setup project to output its own .exe
benvillalobos Aug 31, 2020
b52892f
Working state! (hopefully)
benvillalobos Sep 1, 2020
be4ea05
Remove unused ungac project
benvillalobos Sep 1, 2020
c53a3c0
Cleanup
benvillalobos Sep 1, 2020
1c944fc
csproj cleanup
benvillalobos Sep 1, 2020
d1137ae
Basic documentation
benvillalobos Sep 1, 2020
f2d4c9e
Remove readkey!
benvillalobos Sep 2, 2020
87e9bab
.exe now flows
benvillalobos Sep 2, 2020
a63a2ad
PR Feedback, documentation.
benvillalobos Sep 3, 2020
3cfb13a
Comment linking to the arcade bug.
benvillalobos Sep 3, 2020
49900b2
Add logging for removed assemblies.
benvillalobos Sep 3, 2020
e89501e
Sign UnGAC.exe
benvillalobos Sep 4, 2020
60039b6
Changes from review
benvillalobos Sep 18, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions MSBuild.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2009
# Visual Studio Version 16
VisualStudioVersion = 16.0.30320.27
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4900B3B8-4310-4D5B-B1F7-2FDF9199765F}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -65,6 +65,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MSBuild.Engine.Corext", "sr
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MSBuild.Bootstrap", "src\MSBuild.Bootstrap\MSBuild.Bootstrap.csproj", "{CEAEE4FE-9298-443B-AFC5-0F72472484B6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Build.UnGAC", "src\Package\Microsoft.Build.UnGAC\Microsoft.Build.UnGAC.csproj", "{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -834,6 +836,36 @@ Global
{CEAEE4FE-9298-443B-AFC5-0F72472484B6}.Release-MONO|x64.Build.0 = Release-MONO|x64
{CEAEE4FE-9298-443B-AFC5-0F72472484B6}.Release-MONO|x86.ActiveCfg = Release-MONO|Any CPU
{CEAEE4FE-9298-443B-AFC5-0F72472484B6}.Release-MONO|x86.Build.0 = Release-MONO|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug|x64.ActiveCfg = Debug|x64
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug|x64.Build.0 = Debug|x64
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug|x86.ActiveCfg = Debug|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug|x86.Build.0 = Debug|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug-MONO|Any CPU.ActiveCfg = Debug-MONO|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug-MONO|Any CPU.Build.0 = Debug-MONO|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug-MONO|x64.ActiveCfg = Debug-MONO|x64
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug-MONO|x64.Build.0 = Debug-MONO|x64
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug-MONO|x86.ActiveCfg = Debug-MONO|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Debug-MONO|x86.Build.0 = Debug-MONO|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.MachineIndependent|Any CPU.ActiveCfg = MachineIndependent|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.MachineIndependent|Any CPU.Build.0 = MachineIndependent|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.MachineIndependent|x64.ActiveCfg = MachineIndependent|x64
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.MachineIndependent|x64.Build.0 = MachineIndependent|x64
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.MachineIndependent|x86.ActiveCfg = MachineIndependent|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.MachineIndependent|x86.Build.0 = MachineIndependent|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release|Any CPU.Build.0 = Release|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release|x64.ActiveCfg = Release|x64
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release|x64.Build.0 = Release|x64
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release|x86.ActiveCfg = Release|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release|x86.Build.0 = Release|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release-MONO|Any CPU.ActiveCfg = Release-MONO|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release-MONO|Any CPU.Build.0 = Release-MONO|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release-MONO|x64.ActiveCfg = Release-MONO|x64
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release-MONO|x64.Build.0 = Release-MONO|x64
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release-MONO|x86.ActiveCfg = Release-MONO|Any CPU
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F}.Release-MONO|x86.Build.0 = Release-MONO|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -850,6 +882,7 @@ Global
{16DBDF17-3E0E-4140-989A-B42638126A40} = {9BAD9352-DEFB-45E5-B8A4-4816B9B22A33}
{EDBFE32E-F264-4F01-97C3-B58F8B9165C9} = {9BAD9352-DEFB-45E5-B8A4-4816B9B22A33}
{3D67E4FF-6EC6-4FE7-82F1-0DACE1E399A7} = {9BAD9352-DEFB-45E5-B8A4-4816B9B22A33}
{B60173F0-F9F0-4688-9DF8-9ADDD57BD45F} = {9BAD9352-DEFB-45E5-B8A4-4816B9B22A33}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F948D667-14E3-4F98-BA50-3F3C948BF4C2}
Expand Down
4 changes: 2 additions & 2 deletions eng/Signing.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<ItemGroup>
<FileSignInfo Include="Nerdbank.Streams.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="MessagePack.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="MessagePack.Annotations.dll" CertificateName="3PartySHA2" />
<ItemsToSign Include="$(VisualStudioSetupOutputPath)DevDivPackages\*.nupkg" />
<FileSignInfo Include="MessagePack.Annotations.dll" CertificateName="3PartySHA2" />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused by this; do we not need to sign DevDivPackages*.nupkg anymore?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't sign it in the first place; this line was just in error.

<ItemsToSign Include="$(VisualStudioSetupInsertionPath)Microsoft.Build.UnGAC.exe" />
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions src/Package/MSBuild.VSSetup/files.swr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package name=Microsoft.Build
vs.package.language=neutral

vs.dependencies
vs.dependency id=Microsoft.Build.UnGAC
vs.dependency id=Microsoft.VisualStudio.PackageGroup.NuGet
version=[15.0,17.0)

Expand Down
29 changes: 29 additions & 0 deletions src/Package/Microsoft.Build.UnGAC/Microsoft.Build.UnGAC.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Setup runs on net45 and may not have installed newer yet. -->
<TargetFramework>net45</TargetFramework>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that mean it doesn't work on mac/linux? Is there a way we can make it work on mac/linux?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GAC is a thing only on .NET Framework (on Windows). Things do not break because of the GAC on Mac/Linux, because there's no GAC.

<!-- Set as an exe because this project publishes its own output. -->
<OutputType>Exe</OutputType>
<!-- Forcing the 'vsix' output to be json output. Workaround for https://github.com/dotnet/arcade/issues/6120 -->
<TargetVsixContainerName>Microsoft.Build.UnGAC.exe</TargetVsixContainerName>
<!-- VS Insertion -->
<VisualStudioInsertionComponent>Microsoft.Build.UnGAC</VisualStudioInsertionComponent>
</PropertyGroup>

<ItemGroup>
<_SwixArgs Include="PackageType=manifest"/>
<!-- If we don't set TargetExt to .json, arcade defaults to generating a .vsix -->
<_SwixArgs Include="TargetExt=.json"/>
</ItemGroup>

<!-- SwrProperty is an arcade concept. -->
<ItemGroup>
<!-- BinDir is set via SwrProperty to be passed to the swr compiler. OutDir is the path to the bin folder. See exe.swr to see how this is used. -->
<SwrProperty Include="BinDir=$(OutDir)" />
<!-- Version must constantly update in order for our exe package to run on install and update. -->
<SwrProperty Include="Version=$(VsixVersion)" />

<!-- our swr file must be picked up, this is how we set that. -->
<SwrFile Include="exe.swr" Condition=" '$(MSBuildRuntimeType)' == 'Full' " />
</ItemGroup>
</Project>
22 changes: 22 additions & 0 deletions src/Package/Microsoft.Build.UnGAC/NativeMethods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Runtime.InteropServices;

namespace Microsoft.Build.UnGAC
{
// See: https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/fusion/iassemblycache-interface
[ComImport, Guid("E707DCDE-D1CD-11D2-BAB9-00C04F8ECEAE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAssemblyCache
{
[PreserveSig]
uint UninstallAssembly(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName, IntPtr pRefData, ref ulong pulDisposition);
}

public static class NativeMethods
{
[DllImport("fusion.dll")]
internal static extern uint CreateAssemblyCache(out IAssemblyCache ppAsmCache, int dwReserved);
}
}
53 changes: 53 additions & 0 deletions src/Package/Microsoft.Build.UnGAC/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;

namespace Microsoft.Build.UnGAC
{
/// <summary>
/// Original Issue: https://github.com/dotnet/msbuild/issues/5183
/// This tool was created to help prevent customers from putting MSBuild assemblies in the Global Assembly Cache.
/// It runs at VS install-time as well as repair-time.
/// It is intended to run as best effort. Meaning that if it fails, we avoid throwing and instead log it.
/// </summary>
class Program
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: generic name

{
static void Main(string[] args)
{
try
{
string[] assembliesToUnGAC =
{
"Microsoft.Build, Version=15.1.0.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these the only versions people GAC?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're the only versions that we use, so they're the only ones that need to be removed from the GAC. Prior to VS 15, our assemblies were GACed by design; after they're not and they're all 15.1.0.0.

"Microsoft.Build.Engine, Version=15.1.0.0",
"Microsoft.Build.Framework, Version=15.1.0.0",
"Microsoft.Build.Tasks.Core, Version=15.1.0.0",
"Microsoft.Build.Utilities.Core, Version=15.1.0.0",
"Microsoft.Build.Conversion.Core, Version=15.1.0.0"
};

uint hresult = NativeMethods.CreateAssemblyCache(out IAssemblyCache assemblyCache, 0);

// Most significant bit is set, meaning there was an error in the Hresult.
if ((hresult >> 31) == 1)
{
Console.WriteLine($"Could not successfully call CreateAssemblyCache. HResult: {hresult}");
Comment thread
benvillalobos marked this conversation as resolved.
Console.WriteLine("Exiting without removing assemblies from the GAC...");
return;
}

foreach (string assembly in assembliesToUnGAC)
{
hresult = assemblyCache.UninstallAssembly(dwFlags: 0, pszAssemblyName: assembly, pRefData: IntPtr.Zero, pulDisposition: 0);

Console.WriteLine($"Tried to remove {assembly} from the GAC. HResult: 0x{hresult:X8}");
}
}
catch (Exception e)
{
Console.WriteLine($"Caught an exception! We don't want to throw because we want MSBuild to install.\n" + e.ToString());
}
}
}
}
19 changes: 19 additions & 0 deletions src/Package/Microsoft.Build.UnGAC/exe.swr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use vs

package name=Microsoft.Build.UnGAC
version=$(Version)
vs.package.type=exe
vs.package.chip=neutral
vs.package.language=neutral

vs.installCommand fileName=[Payload]

vs.repairCommand fileName=[Payload]

vs.installSize
SystemDrive=0
TargetDrive=0
SharedDrive=0

vs.payloads
vs.payload source=$(BinDir)Microsoft.Build.UnGAC.exe