0

この SO 投稿に非常によく似た質問があります: TFS Build 2010 - Custom Binary Location and SharePoint WSP。明確な答えはありませんが、提供された唯一の答えは進むべき道のようです。

いくつかのソリューションを構築しており、ソリューションとプロジェクトを独自のフォルダーに配置する必要があります。これにより、ビルド出力が、使用しているテンプレートの MSBuild 呼び出しに変更されます。私はこれを問題なくしばらく使用しています。

最近、ある開発者が、毎日のビルドで .wsp ファイルが生成されていないと不満を漏らしました。これを調べたところ、前述のSO投稿に出くわしました。

指示に従いましたが、新しいエラーが発生しました:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\SharePointTools\Microsoft.VisualStudio.SharePoint.targets (411): メソッドが見つかりません: 'Boolean Microsoft.VisualStudio.SharePoint.PathUtils.HasIllegalDeploymentPathCharacters(System.弦)'。

ターゲット ファイルの次の行 (411) を確認しました。

<PackageFiles LayoutPath="$(LayoutPath)%(EnumeratedFiles.Package)\" PackagePath="$(BasePackagePath)%(EnumeratedFiles.Package).$(PackageExtension)" />

PackageFilesターゲットは次のように定義されています。

<UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="PackageFiles" />

GACを確認しましたが、そこに表示されなかったので追加しました。TFS 2010 ビルド マシンには、Visual Studio 2010 と SharePoint 2010 がインストールされています。このタスクを変更する以外に何もする必要はないと思います:

<CreateSharePointProjectService Configuration="$(Configuration)"
                                Platform="$(Platform)"
                                ProjectFile="$(MSBuildProjectFile)"
                                ProjectReferences="@(SharePointProjectReference)"
                                OutDir="$(TargetDir)">
  <Output PropertyName="ProjectService" TaskParameter="ProjectService" />
</CreateSharePointProjectService>

OutDirが $(TargetDir) を指すようにします。

メソッドが見つからないこのエラーが発生する理由について、何か不足していますか? Google Fu を使用しているにもかかわらず、ウェブ上に情報がないため、このエラーは非常に腹立たしいものです。

更新 ビルド サーバー上にある Microsoft.VisualStudio.SharePoint.dll を分解しました。PathUtils クラスまたは Namespace はありません。このファイルのバージョンが悪い可能性はありますか? どうすればこれを検出できますか? ビルド サーバーに SharePoint SDK をインストールする必要がありますか。すでにSharepoint 2010がインストールされています。

更新 2
GAC を確認しました。Microsoft.VisualStudio.Sharepoint アセンブリが表示されます。ただし、Visual Studio コマンド プロンプトの x64 バージョンを実行している場合にのみ見つけることができます。通常のものを実行すると、アセンブリが返されません。これは、Sharepoint アセンブリが 64 ビットであるためだと思います。私の知る限り、TFS は 64 ビットに設定されています。これは私の問題でしょうか?

4

3 に答える 3

2

PathUtils.HasIllegalDeploymentPathCharacters メソッドは、Microsoft.VisualStudio.SharePoint.Designers.Models.dll のバージョン 10.0.40219.1 に存在し、バージョン 10.0.30319.1 (このエラーが表示された場所) には存在しません。

于 2013-01-14T01:58:29.840 に答える
0

この問題の解決策を見つけました。誰もこれに遭遇したことはないと思うので、「正しい」解決策があるかどうかは疑わしいです。.wspファイルをソリューションに組み込むために行ったことをここに投稿します。

より良い解決策があると思われる場合、または問題を解決する私の方法が標準に達していない場合は、必ず回答を投稿してください(またはこの回答または元の質問にコメントしてください)。

問題を解決するために思いついた手順でこれを説明します。

最初のステップPackageFiles タスクで問題が発生しました。このタスクは、呼び出すメソッドを見つけることができませんでした。ファイルC:\ Program Files(x86)\ MSBuild \ Microsoft \ VisualStudio \ v10.0 \ SharePointTools \ Microsoft.VisualStudio.SharePoint.targetsを見ると、56行目でこれを見つけることができます。

<UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="PackageFiles" /> 

PackageFilesタスク/クラスを探す場所を知っていました。

ステップ2 どこを見ればよいかを知った後、タスクを逆コンパイルしました。TelerikのJustDecompileを使用しましたが、Reflectorでも同じコードを思いつきました。

私ははっきりと線を見ることができました:

if (PathUtils.HasIllegalDeploymentPathCharacters(str2))

これはエラーでした。

ステップ3 結局、PathUtils.HasIllegalDeploymentPathCharactersメソッドが安全チェックとしてそこにあると判断しました。このタスクを自分のカスタムライブラリで再作成してから、カスタムターゲットファイルに挿入することができます。

これが私が思いついたクラスでした:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using Microsoft.VisualStudio.SharePoint.Tasks;
using Microsoft.Build.Framework;

namespace SharepointTaskLibrary
{
  public class PackageFiles : BuildTask
  {
    [Required]
    public ITaskItem LayoutPath
    {
      get;
      set;
    }

    [Required]
    public ITaskItem PackagePath
    {
      get;
      set;
    }

    public PackageFiles()
    {

    }

    protected override void OnCheckParameters()
    {
      if (this.LayoutPath == null)
      {
        throw new InvalidOperationException(Strings.GetString("LayoutPathNotSpecified"));
      }
      if (this.PackagePath == null)
      {
        throw new InvalidOperationException(Strings.GetString("PackagePathNotSpecified"));
      }
    }

    protected override void OnExecute()
    {
      object[] objArray;
      object[] objArray2;
      object[] objArray3;
      string metadata = this.LayoutPath.GetMetadata("FullPath");
      string str1 = this.PackagePath.GetMetadata("FullPath");

      Assembly sharepointTasksAss = Assembly.Load("Microsoft.VisualStudio.SharePoint.Tasks");

      if (sharepointTasksAss != null)
        base.Log.LogMessage(MessageImportance.High, "Found Tasks assembly!");
      else
      {
        base.Log.LogError("Couldn't find the tasks assembly");
        return;
      }

      if (!Directory.Exists(metadata))
      {
        base.Log.LogErrorFromResources("LayoutPathDoesNotExist", new object[] { metadata });
      }
      else
      {
        MethodInfo createCabMethod = GetStaticMethod(sharepointTasksAss, "Microsoft.VisualStudio.SharePoint.Tasks.Utilities.CabCreator", "CreateCabinet");

        if (createCabMethod == null)
        {
          base.Log.LogError("the method could not be retrieved on type.");
          return;
        }
        else
          base.Log.LogMessage(MessageImportance.High, "Found method: " + createCabMethod.Name);

        IEnumerable<string> strs = createCabMethod.Invoke(null, new object[] { metadata, str1 }) as IEnumerable<string>;

        /*
         * The following code would error in the original task.
         */
        //foreach (string str2 in strs)
        //{
        //  if (PathUtils.HasIllegalDeploymentPathCharacters(str2))
        //  {
        //    base.Log.LogWarningFromResources("FileNameContainsIllegalDeploymentPathCharacters", new object[] { str2 });
        //  }
        //}
        base.Log.LogMessage(MessageImportance.High, Strings.GetString("PackageCreatedSuccessfully"), new object[] { str1 });
      }

      Type codeMarkersType = null;

      try
      {
        codeMarkersType = sharepointTasksAss.GetType("Microsoft.Internal.Performance.CodeMarkers", true);
      }
      catch (Exception e)
      {
        base.Log.LogErrorFromException(e, true);
      }

      if (codeMarkersType == null)
      {
        base.Log.LogError("Couldn't get the CodeMarkers class!");
        return;
      }
      else
        base.Log.LogMessage(MessageImportance.High, "Found the type: " + codeMarkersType.FullName);

      /*
       * This has yet to be added back in.
       */
      //CodeMarkers.Instance.CodeMarker(CodeMarkerEvent.perfSharePointPackageWspPackageEnd);
    }

    private MethodInfo GetStaticMethod(Assembly assembly, string typeName, string methodName)
    {
      Type type = null;

      try
      {
        type = assembly.GetType(typeName, true);
      }
      catch (Exception e)
      {
        base.Log.LogErrorFromException(e, true);
      }

      if (type == null)
      {
        base.Log.LogError("Couldn't get the type: " + typeName);
        return null;
      }
      else
        base.Log.LogMessage(MessageImportance.High, "Found the type: " + type.FullName);

      MethodInfo methodInfo = type.GetMethod(methodName, BindingFlags.Static);

      if (methodInfo == null)
      {
        MethodInfo[] methods = type.GetMethods().Union(type.GetMethods(BindingFlags.Static)).ToArray();

        base.Log.LogWarning(string.Format("Wasn't able to find {0} directly. Searching through the static {1} method(s) on {2}", methodName, methods.Length, type.FullName));

        foreach (MethodInfo info in methods)
        {
          if (info.Name == methodName && methodInfo == null)
            methodInfo = info;
        }

        if (methodInfo == null)
        {
          MemberInfo[] members =
                  type.GetMembers().Union(type.GetMembers(BindingFlags.Static | BindingFlags.NonPublic)).Union(type.GetMembers(BindingFlags.NonPublic)).ToArray();

          base.Log.LogWarning(string.Format("Wasn't able to find {0}. Searching through the {1} members(s) on {2}", methodName, methods.Length, type.FullName));

          MemberInfo createCabMember = null;

          foreach (MemberInfo member in members)
          {
            if (member.Name == methodName)
            {
              createCabMember = member;
              break;
            }
            else
              base.Log.LogMessage(MessageImportance.High, "Found member: " + member.Name);
          }

          if (createCabMember == null)
            base.Log.LogError("Still wasn't able to find " + methodName + " in the members!");
        }
      }

      return methodInfo;
    }
  }
}

ほとんどのクラスとメソッドは内部としてマークされているため、実際にcab/wspファイルをビルドするために必要なタイプとメソッドを取得するためにリフレクションを使用する必要がありました。これは、次のメソッドで実行されます:GetStaticMethod

ステップ4逆コンパイルされたコードとクラスのカスタムバージョンを読むと、 Stringsクラス に気付くでしょう。リソースアクセサクラスのようです。そのコードも逆コンパイルして、文字列リソースにアクセスするたびに反映するのではなく、カスタムタスクを作成するソリューションで使用することにしました。このファイルにはthis.GetType()。Assemblyという行が含まれているため、このファイルは直接逆コンパイルされませんでした。リソースを含む現在のアセンブリを取得するために使用します。これは元のアセンブリ内では正常に機能しますが、このカスタムアセンブリで問題が発生します。

元の行:

internal Strings()
{
    this.resources = new ResourceManager("Strings", this.GetType().Assembly);
}

この行は次のように変更する必要がありました。

Assembly sharepointTasksAss = Assembly.Load("Microsoft.VisualStudio.SharePoint.Tasks");
this.resources = new ResourceManager("Strings", sharepointTasksAss);

ステップ5 オリジナルを模倣するカスタムビルドタスクを実行した後、それをターゲットファイルに配置する必要がありました。次に、元のターゲットファイルをバックアップし、次のようにUsingTaskセクションを置き換えるカスタムファイルを作成しました。

  <UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="CreateSharePointProjectService" />
  <UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="EnumerateFiles" />
  <UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="EnumerateFeature" />
  <UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="EnumeratePackage" />
  <UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="EnumerateProjectItem" />
  <UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="LayoutFiles" />
  <!-- The next task is a mimic of the one from the other assembly.  I decompiled it and recreated it so it wouldn't error.  LOL -->
  <UsingTask AssemblyFile="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\SharePointTools\SharepointTaskLibrary.dll" TaskName="PackageFiles" />
  <UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="ResolveProjectMember" />
  <UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="SetPackagingProperties" />
  <UsingTask AssemblyFile="Microsoft.VisualStudio.SharePoint.Tasks.dll" TaskName="ValidatePackage" />

これはタスクは、カスタムタスクを含むDLLを指します。具体的には、この行:

<UsingTask AssemblyFile="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\SharePointTools\SharepointTaskLibrary.dll" TaskName="PackageFiles" />

最後
に、コンパイルされたDLLと編集されたターゲットファイルをC:\ Program Files(x86)\ MSBuild \ Microsoft \ VisualStudio \ v10.0 \ SharePointToolsディレクトリにドロップしました(ここでも元のターゲットファイルをバックアップします)。

これにより、SharePointソリューションによって生成されたwspファイルをカスタム出力するTFS2010を介してビルドすることができました。

このサイトをリソースとして使用しました:http: //blogs.like10.com/2011/08/04/team-build-2010-customized-output-directories-sharepoint-2010-wsps/

(リソースとして別の1つまたは2つのサイトを使用した可能性がありますが、現時点ではブラウザーの履歴でそれらを見つけることができます)。

あなたのマイレージは変わるかもしれませんが、誰かがこの同様の問題を抱えていて、「ハッキングされていない」方法でそれを修正できるかどうか私に知らせてください。

更新
この問題全体は、私が管理していた元のTFSインストールに起因しているようです。私は最近、完全に新しいOSインストールと新しいデータベースサーバーを備えた適切なTFSサーバー(2012)にチームを移動しました。データベースを移行してTFSでアップグレードタスクを実行すると、ビルドを2012で機能させるためにいくつかの小さなビルド編集を行うことができましたが、この問題は2度目に発生しませんでした。元の2010TFSは変換された開発マシン上にあったため、この問題が発生したと思います。

于 2012-05-29T15:16:29.587 に答える
0

アセンブリ「Microsoft.VisualStudio.SharePoint.Designers.Models.dll」がありません

次のアセンブリをビルド システムの GAC にコピーする必要があります。

Microsoft.VisualStudio.SharePoint.Designers.Models.dll Microsoft.VisualStudio.SharePoint.Designers.Models.Features.dll Microsoft.VisualStudio.SharePoint.Designers.Models.Packages.dll Microsoft.VisualStudio.SharePoint.dll

必要なアセンブリの詳細については、次の記事を参照してください。

http://msdn.microsoft.com/en-us/ff622991.aspx

よろしく、

ウェス・マクドナルド

于 2012-05-30T17:33:28.670 に答える