8000 Ensure that Microsoft.TeamFoundation assemblies are loaded consistently · github/VisualStudio@18dd2f3 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 18dd2f3

Browse files
committed
Ensure that Microsoft.TeamFoundation assemblies are loaded consistently
Added a workaround related to #923 that gives our resolver a chance to run first. Be more specific about which assemblies might be resolved (include PublicKeyToken). They must start with "Microsoft.TeamFoundation." and end with ", PublicKeyToken=b03f5f7f11d50a3a".
1 parent 3f91b83 commit 18dd2f3

File tree

1 file changed

+33
-5
lines changed

1 file changed

+33
-5
lines changed

src/GitHub.VisualStudio/TeamFoundation/TeamFoundationResolver.cs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ namespace GitHub.TeamFoundation
1111
public class TeamFoundationResolver : IDisposable
1212
{
1313
const string BindingPath = @"CommonExtensions\Microsoft\TeamFoundation\Team Explorer";
14-
const string AssemblyPrefix = "Microsoft.TeamFoundation.";
14+
const string AssemblyStartsWith = "Microsoft.TeamFoundation.";
15+
const string AssemblyEndsWith = ", PublicKeyToken=b03f5f7f11d50a3a";
1516

1617
internal static Type Resolve(Func<Type> func)
1718
{
@@ -31,7 +32,34 @@ internal static object Resolve(Func<object> func)
3132

3233
internal TeamFoundationResolver()
3334
{
34-
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
35+
TryAddPriorityAssemblyResolve(AppDomain.CurrentDomain, CurrentDomain_AssemblyResolve);
36+
}
37+
38+
// NOTE: This is a workaround for https://github.com/github/VisualStudio/issues/923#issuecomment-287537118
39+
// A consistent repro was to open Vsiaul Studio 2015 by double clicking on GitHubVS.sln.
40+
// The `Microsoft.TeamFoundation.Controls.dll` assembly referenced by this solution would
41+
// be copied to and loaded from the following location:
42+
// C:\Users\<user>\AppData\Local\Microsoft\VisualStudio\14.0\ProjectAssemblies\ffp8wnnz01\Microsoft.TeamFoundation.Controls.dll
43+
//
44+
// This method ensures that our resolver has a chance to resolve it first.
45+
static void TryAddPriorityAssemblyResolve(AppDomain domain, ResolveEventHandler handler)
46+
{
47+
try
48+
{
49+
var resolveField = typeof(AppDomain).GetField("_AssemblyResolve", BindingFlags.NonPublic | BindingFlags.Instance);
50+
var assemblyResolve = (ResolveEventHandler)resolveField.GetValue(domain);
51+
if (assemblyResolve != null)
52+
{
53+
handler = (ResolveEventHandler)Delegate.Combine(handler, assemblyResolve);
54+
}
55+
56+
resolveField.SetValue(domain, handler);
57+
}
58+
catch (Exception e)
59+
{
60+
Trace.WriteLine("Couldn't add priority AssemblyResolve handler (adding normal handler): " + e);
61+
domain.AssemblyResolve += handler;
62+
}
3563
}
3664

3765
public void Dispose()
@@ -44,19 +72,19 @@ Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
4472
try
4573
{
4674
var name = args.Name;
47-
if (name.StartsWith(AssemblyPrefix))
75+
if (name.StartsWith(AssemblyStartsWith) && name.EndsWith(AssemblyEndsWith))
4876
{
4977
var assemblyName = new AssemblyName(name);
5078
var path = GetTeamExplorerPath(assemblyName.Name);
51-
if(File.Exists(path))
79+
if (File.Exists(path))
5280
{
5381
return Assembly.LoadFrom(path);
5482
}
5583
}
5684
}
5785
catch (Exception e)
5886
{
59-
Trace.WriteLine(e);
87+
Trace.WriteLine("Couldn't resolve TeamFoundation assembly: " + e);
6088
}
6189

6290
return null;

0 commit comments

Comments
 (0)
0