如何调用Workstation.GetLocalWorkspaceInfo的方式适用于使用VS2012的用户以及使用VS2013而不使用反射的用户?

时间:2014-10-29 03:16:07

标签: c# visual-studio-2012 tfs visual-studio-2013

Workstation.Current.GetLocalWorkspaceInfo(string)返回与给定本地目录关联的WorkspaceInfo对象。

所以,我编写了一个简单的程序,显示给定本地目录名称的工作区名称。 它在我的机器上运行良好,但在另一台机器上不起作用。

两者的区别在于我的运行VS2012而另一个运行VS2013。对于我的生活,我无法理解。两个工作区都链接到同一个TFS服务器2010。

在阅读TFS API: GetLocalWorkspaceInfo always returns null之后,我将Microsoft.TeamFoundation.XXX引用替换为在第二台机器上找到的引用,它再次起作用。但是,当然,它停止在我的机器上工作。

这不是正确的方法。我一定是在做错事。

我希望单个可执行文件适用于两台计算机而无需借助反射。我的问题很简单 - 如何?

完整的源代码可以在这里找到 - https://bitbucket.org/markkharitonov/tfsinsanity/src。基本上,两个项目共享完全相同的源代码,但使用了一组不同的依赖项。

主要源代码是:

private static Workspace GetWorkspace(string wsRoot, string wsName, string wsOwner)
{
    var coll = new TfsTeamProjectCollection(new Uri("http://torsvtfs01:8080/tfs/DefaultCollection"));
    var vcs = (VersionControlServer)coll.GetService(typeof(VersionControlServer));
    WorkspaceInfo wsInfo;
    if (wsRoot == null)
    {
        Console.WriteLine(Workstation.Current.Name);
        wsInfo = Workstation.Current.GetLocalWorkspaceInfo(vcs, wsName, wsOwner);
        if (wsInfo == null)
        {
            throw new Exception(string.Format("Failed to identify the workspace {0};{1}", wsName, wsOwner));
        }
    }
    else
    {
        wsInfo = Workstation.Current.GetLocalWorkspaceInfo(wsRoot);
        if (wsInfo == null)
        {
            throw new Exception(string.Format("Failed to identify the workspace corresponding to \"{0}\"", wsRoot));
        }
    }
    return wsInfo.GetWorkspace(coll);
}

这是如何在我的机器上运行的(VS2012):

PS C:\work\GetShelvedChangeset> tf workspaces
Collection: http://torsvtfs01:8080/tfs/defaultcollection
Workspace Owner                Computer Comment
--------- -------------------- -------- ------------------------------------------------------------------------------------
CANWS212  DAYFORCE\mkharitonov CANWS212
PS C:\work\GetShelvedChangeset> .\bin\Debug2012\GetShelvedChangeset.exe --wsRoot C:\dayforce\SharpTop
Microsoft.TeamFoundation.VersionControl.Client, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Workspace instance -784339741
  Comment:
  Computer: CANWS212
  EffectivePermissions: 0
  Folders: [0]
  IsLocalWorkspace: False
  LastAccessDate: 1/1/0001 12:00:00 AM
  Name: CANWS212
  Options: 0
  OwnerAliases: [0]
  OwnerDisplayName: DAYFORCE\mkharitonov
  OwnerIdentifier:
  OwnerIdentityType:
  OwnerName: DAYFORCE\mkharitonov
  OwnerUniqueName:
  SecurityToken: /CANWS212;34be4ed8-c4fd-4e9f-bdae-d1843df36b0f
PS C:\work\GetShelvedChangeset> .\bin\Debug2013\GetShelvedChangeset.exe --wsRoot C:\dayforce\SharpTop
Failed to identify the workspace corresponding to "C:\dayforce\SharpTop"
PS C:\work\GetShelvedChangeset>

在另一台机器上:

PS C:\tfs\DFGatedCheckInTest2\Build\2010\scripts> &"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\tf.exe" workspaces
Collection: http://torsvtfs01:8080/tfs/defaultcollection
Workspace            Owner             Computer     Comment
-------------------- ----------------- ------------ ----------------------------------------------------------------------------------------
1733_TORSVBUILD10    DAYFORCE\tfsbuild TORSVBUILD10 Workspace Created by Team Build
1846_91_TORSVBUILD10 DAYFORCE\tfsbuild TORSVBUILD10 Workspace Created by Team Build
1846_92_TORSVBUILD10 DAYFORCE\tfsbuild TORSVBUILD10 Workspace Created by Team Build
PS C:\tfs\DFGatedCheckInTest2\Build\2010\scripts> .\debug2012\GetShelvedChangeset.exe --wsRoot C:\tfs\DFGatedCheckInTest2
Failed to identify the workspace corresponding to "C:\tfs\DFGatedCheckInTest2"
PS C:\tfs\DFGatedCheckInTest2\Build\2010\scripts> .\debug2013\GetShelvedChangeset.exe --wsRoot C:\tfs\DFGatedCheckInTest2
Microsoft.TeamFoundation.VersionControl.Client, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Workspace instance 215494889
  Comment: Workspace Created by Team Build
  Computer: TORSVBUILD10
  EffectivePermissions: 0
  Folders: [0]
  IsLocalWorkspace: False
  LastAccessDate: 1/1/0001 12:00:00 AM
  Name: 1733_TORSVBUILD10
  Options: 0
  OwnerAliases: [0]
  OwnerDisplayName: DAYFORCE\tfsbuild
  OwnerIdentifier:
  OwnerIdentityType:
  OwnerName: DAYFORCE\tfsbuild
  OwnerUniqueName:
  SecurityToken: /1733_TORSVBUILD10;f2899138-af14-4449-9f6d-78a0fbccebb8
PS C:\tfs\DFGatedCheckInTest2\Build\2010\scripts>

2 个答案:

答案 0 :(得分:3)

在这种情况下,方法签名应该是相同的,您只需要担心首先引用正确的DLL。您应该能够链接到较新的DLL并使用绑定重定向为安装了VS 2012的用户加载DLL。

We used this method successfully in a previous product to provide TFS 2005 and 2008 compatibility.

简而言之,您创建了一个自定义程序集解析程序。在这里,当我们无法加载与之链接的VS 2013版本时,我们将尝试从VS 2012加载所有Microsoft.TeamFoundation.* DLL:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);

public static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
{
    String[] arguments = args.Name.Split(new string[] { ", ", "," }, 
        StringSplitOptions.RemoveEmptyEntries);
    String assemblyName = arguments[0];

    if(assemblyName.StartsWith("Microsoft.TeamFoundation.", StringComparison.CurrentCultureIgnoreCase))
    {
        return Assembly.Load(assemblyName + ", Version=11.0.0.0");
    }

    return null;
}

(请注意,您应该检查所请求的版本号并将文化信息传递给加载程序,如博客文章中所述,但此代码段应足以让您入门。)

答案 1 :(得分:0)

通过将CopyLocal属性设置为Always,将项目引用的TFS程序集添加到可执行文件中。