diff --git a/GitTfs.Vs2008/TfsHelper.Vs2008.cs b/GitTfs.Vs2008/TfsHelper.Vs2008.cs index 8c9d4523..ecbbbc56 100644 --- a/GitTfs.Vs2008/TfsHelper.Vs2008.cs +++ b/GitTfs.Vs2008/TfsHelper.Vs2008.cs @@ -48,6 +48,8 @@ namespace Sep.Git.Tfs.Vs2008 return VersionControl.AuthenticatedUser; } + public void SetPathResolver() { } + public override bool CanShowCheckinDialog { get { return false; } diff --git a/GitTfs.Vs2010/TfsHelper.Vs2010.cs b/GitTfs.Vs2010/TfsHelper.Vs2010.cs index 0ca30229..a2a03b69 100644 --- a/GitTfs.Vs2010/TfsHelper.Vs2010.cs +++ b/GitTfs.Vs2010/TfsHelper.Vs2010.cs @@ -71,51 +71,16 @@ namespace Sep.Git.Tfs.Vs2010 return VersionControl.AuthorizedUser; } - public override bool CanShowCheckinDialog { get { return true; } } + private string vsInstallDir; - public override long ShowCheckinDialog(IWorkspace workspace, IPendingChange[] pendingChanges, IEnumerable checkedInfos, string checkinComment) + protected override string GetVsInstallDir() { - return ShowCheckinDialog(_bridge.Unwrap(workspace), - pendingChanges.Select(p => _bridge.Unwrap(p)).ToArray(), - checkedInfos.Select(c => _bridge.Unwrap(c)).ToArray(), - checkinComment); - } - - private long ShowCheckinDialog(Workspace workspace, PendingChange[] pendingChanges, - WorkItemCheckedInfo[] checkedInfos, string checkinComment) - { - using (var parentForm = new ParentForm()) + if (vsInstallDir == null) { - parentForm.Show(); - - var dialog = Activator.CreateInstance(GetCheckinDialogType(), new object[] {workspace.VersionControlServer}); - - return dialog.Call("Show", parentForm.Handle, workspace, pendingChanges, pendingChanges, - checkinComment, null, null, checkedInfos); + vsInstallDir = TryGetRegString(@"Software\Microsoft\VisualStudio\10.0", "InstallDir") + ?? TryGetRegString(@"Software\WOW6432Node\Microsoft\VisualStudio\10.0", "InstallDir"); } - } - - private const string DialogAssemblyName = "Microsoft.TeamFoundation.VersionControl.ControlAdapter"; - - private static Type GetCheckinDialogType() - { - return GetDialogAssembly().GetType(DialogAssemblyName + ".CheckinDialog"); - } - - private static Assembly GetDialogAssembly() - { - return Assembly.LoadFrom(GetDialogAssemblyPath()); - } - - private static string GetDialogAssemblyPath() - { - return Path.Combine(GetVs2010InstallDir(), "PrivateAssemblies", DialogAssemblyName + ".dll"); - } - - private static string GetVs2010InstallDir() - { - return TryGetRegString(@"Software\Microsoft\VisualStudio\10.0", "InstallDir") - ?? TryGetRegString(@"Software\WOW6432Node\Microsoft\VisualStudio\10.0", "InstallDir"); + return vsInstallDir; } private static string TryGetRegString(string path, string name) diff --git a/GitTfs.Vs2012/TfsHelper.Vs2012.cs b/GitTfs.Vs2012/TfsHelper.Vs2012.cs index 30acdb86..0cab79f6 100644 --- a/GitTfs.Vs2012/TfsHelper.Vs2012.cs +++ b/GitTfs.Vs2012/TfsHelper.Vs2012.cs @@ -10,12 +10,18 @@ namespace Sep.Git.Tfs.Vs2012 { } + private string vsInstallDir; + protected override string GetVsInstallDir() { - return TryGetRegString(@"Software\Microsoft\VisualStudio\11.0", "InstallDir") - ?? TryGetRegString(@"Software\WOW6432Node\Microsoft\VisualStudio\11.0", "InstallDir") - ?? TryGetUserRegString(@"Software\Microsoft\WDExpress\11.0_Config", "InstallDir") - ?? TryGetUserRegString(@"Software\WOW6432Node\Microsoft\WDExpress\11.0_Config", "InstallDir"); + if (vsInstallDir == null) + { + vsInstallDir = TryGetRegString(@"Software\Microsoft\VisualStudio\11.0", "InstallDir") + ?? TryGetRegString(@"Software\WOW6432Node\Microsoft\VisualStudio\11.0", "InstallDir") + ?? TryGetUserRegString(@"Software\Microsoft\WDExpress\11.0_Config", "InstallDir") + ?? TryGetUserRegString(@"Software\WOW6432Node\Microsoft\WDExpress\11.0_Config", "InstallDir"); + } + return vsInstallDir; } } } diff --git a/GitTfs.Vs2013/TfsHelper.Vs2013.cs b/GitTfs.Vs2013/TfsHelper.Vs2013.cs index 5643dd91..c71656d1 100644 --- a/GitTfs.Vs2013/TfsHelper.Vs2013.cs +++ b/GitTfs.Vs2013/TfsHelper.Vs2013.cs @@ -10,12 +10,18 @@ namespace Sep.Git.Tfs.Vs2013 { } + private string vsInstallDir; + protected override string GetVsInstallDir() { - return TryGetRegString(@"Software\Microsoft\VisualStudio\12.0", "InstallDir") + if (vsInstallDir == null) + { + vsInstallDir = TryGetRegString(@"Software\Microsoft\VisualStudio\12.0", "InstallDir") ?? TryGetRegString(@"Software\WOW6432Node\Microsoft\VisualStudio\12.0", "InstallDir") ?? TryGetUserRegString(@"Software\Microsoft\WDExpress\12.0_Config", "InstallDir") ?? TryGetUserRegString(@"Software\WOW6432Node\Microsoft\WDExpress\12.0_Config", "InstallDir"); + } + return vsInstallDir; } } } diff --git a/GitTfs.VsCommon/TfsHelper.Common.cs b/GitTfs.VsCommon/TfsHelper.Common.cs index 5e13aade..e345687f 100644 --- a/GitTfs.VsCommon/TfsHelper.Common.cs +++ b/GitTfs.VsCommon/TfsHelper.Common.cs @@ -15,7 +15,6 @@ using Sep.Git.Tfs.Core.TfsInterop; using Sep.Git.Tfs.Util; using StructureMap; using StructureMap.Attributes; -using ChangeType = Microsoft.TeamFoundation.Server.ChangeType; namespace Sep.Git.Tfs.VsCommon { diff --git a/GitTfs.VsCommon/TfsHelper.PostVs2010.Common.cs b/GitTfs.VsCommon/TfsHelper.PostVs2010.Common.cs index 2e79ed3d..ca21c9ef 100644 --- a/GitTfs.VsCommon/TfsHelper.PostVs2010.Common.cs +++ b/GitTfs.VsCommon/TfsHelper.PostVs2010.Common.cs @@ -3,11 +3,14 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection; using Microsoft.TeamFoundation.Client; using Microsoft.TeamFoundation.VersionControl.Client; using Sep.Git.Tfs.Core; using Sep.Git.Tfs.Core.TfsInterop; +using Sep.Git.Tfs.Util; using StructureMap; +using ChangeType = Microsoft.TeamFoundation.VersionControl.Client.ChangeType; namespace Sep.Git.Tfs.VsCommon { @@ -15,11 +18,17 @@ namespace Sep.Git.Tfs.VsCommon { TfsApiBridge _bridge; protected TfsTeamProjectCollection _server; + private static bool _resolverInstalled; public TfsHelperVs2010Base(TextWriter stdout, TfsApiBridge bridge, IContainer container) : base(stdout, bridge, container) { _bridge = bridge; + if (!_resolverInstalled) + { + AppDomain.CurrentDomain.AssemblyResolve += LoadFromVsFolder; + _resolverInstalled = true; + } } public override bool CanGetBranchInformation @@ -214,6 +223,64 @@ namespace Sep.Git.Tfs.VsCommon { VersionControl.CreateBranchObject(new BranchProperties(new ItemIdentifier(tfsRepositoryPath))); } + + protected abstract string GetVsInstallDir(); + + /// + /// Help the TFS client find checkin policy assemblies. + /// + Assembly LoadFromVsFolder(object sender, ResolveEventArgs args) + { + Trace.WriteLine("Looking for assembly " + args.Name + " ..."); + string folderPath = Path.Combine(GetVsInstallDir(), "PrivateAssemblies"); + string assemblyPath = Path.Combine(folderPath, new AssemblyName(args.Name).Name + ".dll"); + if (File.Exists(assemblyPath) == false) + return null; + Trace.WriteLine("... loading " + args.Name + " from " + assemblyPath); + Assembly assembly = Assembly.LoadFrom(assemblyPath); + return assembly; + } + + public override bool CanShowCheckinDialog { get { return true; } } + + public override long ShowCheckinDialog(IWorkspace workspace, IPendingChange[] pendingChanges, IEnumerable checkedInfos, string checkinComment) + { + return ShowCheckinDialog(_bridge.Unwrap(workspace), + pendingChanges.Select(p => _bridge.Unwrap(p)).ToArray(), + checkedInfos.Select(c => _bridge.Unwrap(c)).ToArray(), + checkinComment); + } + + private long ShowCheckinDialog(Workspace workspace, PendingChange[] pendingChanges, + WorkItemCheckedInfo[] checkedInfos, string checkinComment) + { + using (var parentForm = new ParentForm()) + { + parentForm.Show(); + + var dialog = Activator.CreateInstance(GetCheckinDialogType(), new object[] { workspace.VersionControlServer }); + + return dialog.Call("Show", parentForm.Handle, workspace, pendingChanges, pendingChanges, + checkinComment, null, null, checkedInfos); + } + } + + private const string DialogAssemblyName = "Microsoft.TeamFoundation.VersionControl.ControlAdapter"; + + private Type GetCheckinDialogType() + { + return GetDialogAssembly().GetType(DialogAssemblyName + ".CheckinDialog"); + } + + private Assembly GetDialogAssembly() + { + return Assembly.LoadFrom(GetDialogAssemblyPath()); + } + + private string GetDialogAssemblyPath() + { + return Path.Combine(GetVsInstallDir(), "PrivateAssemblies", DialogAssemblyName + ".dll"); + } } } diff --git a/GitTfs.VsCommon/TfsHelper.Vs2012Base.cs b/GitTfs.VsCommon/TfsHelper.Vs2012Base.cs index 47cd58e9..726e7d89 100644 --- a/GitTfs.VsCommon/TfsHelper.Vs2012Base.cs +++ b/GitTfs.VsCommon/TfsHelper.Vs2012Base.cs @@ -76,49 +76,6 @@ namespace Sep.Git.Tfs.VsCommon return Retry.Do(() => changeset.AssociatedWorkItems.Length > 0); } - public override bool CanShowCheckinDialog { get { return true; } } - - public override long ShowCheckinDialog(IWorkspace workspace, IPendingChange[] pendingChanges, IEnumerable checkedInfos, string checkinComment) - { - return ShowCheckinDialog(_bridge.Unwrap(workspace), - pendingChanges.Select(p => _bridge.Unwrap(p)).ToArray(), - checkedInfos.Select(c => _bridge.Unwrap(c)).ToArray(), - checkinComment); - } - - private long ShowCheckinDialog(Workspace workspace, PendingChange[] pendingChanges, - WorkItemCheckedInfo[] checkedInfos, string checkinComment) - { - using (var parentForm = new ParentForm()) - { - parentForm.Show(); - - var dialog = Activator.CreateInstance(GetCheckinDialogType(), new object[] {workspace.VersionControlServer}); - - return dialog.Call("Show", parentForm.Handle, workspace, pendingChanges, pendingChanges, - checkinComment, null, null, checkedInfos); - } - } - - private const string DialogAssemblyName = "Microsoft.TeamFoundation.VersionControl.ControlAdapter"; - - private Type GetCheckinDialogType() - { - return GetDialogAssembly().GetType(DialogAssemblyName + ".CheckinDialog"); - } - - private Assembly GetDialogAssembly() - { - return Assembly.LoadFrom(GetDialogAssemblyPath()); - } - - private string GetDialogAssemblyPath() - { - return Path.Combine(GetVsInstallDir(), "PrivateAssemblies", DialogAssemblyName + ".dll"); - } - - protected abstract string GetVsInstallDir(); - protected string TryGetUserRegString(string path, string name) { return TryGetRegString(Registry.CurrentUser, path, name); diff --git a/GitTfs.VsFake/TfsHelper.VsFake.cs b/GitTfs.VsFake/TfsHelper.VsFake.cs index ad434079..dcda17f1 100644 --- a/GitTfs.VsFake/TfsHelper.VsFake.cs +++ b/GitTfs.VsFake/TfsHelper.VsFake.cs @@ -45,6 +45,8 @@ namespace Sep.Git.Tfs.VsFake public void EnsureAuthenticated() {} + public void SetPathResolver() {} + public bool CanShowCheckinDialog { get { return false; } } public long ShowCheckinDialog(IWorkspace workspace, IPendingChange[] pendingChanges, IEnumerable checkedInfos, string checkinComment) diff --git a/GitTfs/Core/TfsWorkspace.cs b/GitTfs/Core/TfsWorkspace.cs index 8756668f..8d1c079f 100644 --- a/GitTfs/Core/TfsWorkspace.cs +++ b/GitTfs/Core/TfsWorkspace.cs @@ -65,7 +65,7 @@ namespace Sep.Git.Tfs.Core var newChangesetId = _tfsHelper.ShowCheckinDialog(_workspace, pendingChanges, GetWorkItemCheckedInfos(), checkinComment); if (newChangesetId <= 0) - throw new GitTfsException("Checkin cancelled!"); + throw new GitTfsException("Checkin canceled!"); return newChangesetId; } diff --git a/GitTfs/GitTfs.csproj b/GitTfs/GitTfs.csproj index 2f111b5c..a12573ee 100644 --- a/GitTfs/GitTfs.csproj +++ b/GitTfs/GitTfs.csproj @@ -88,6 +88,9 @@ true true + + app.manifest + False @@ -255,6 +258,7 @@ Always + diff --git a/GitTfs/app.manifest b/GitTfs/app.manifest new file mode 100644 index 00000000..10cfbf5a --- /dev/null +++ b/GitTfs/app.manifest @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + +