2016-04-30 26 views
1

私は自分のアプリケーションにスクリプトの可能性を追加しています。 Initメソッドはスクリプトをロードし、コンパイルしてスクリプトInitメソッドを呼び出します。私は、私のアプリケーションにVisual Studioのデバッガを接続し、IDEで通常の方法でスクリプトにブレークポイントを追加できるようにしたいと思います。動的にコンパイルされたアセンブリのシンボルをロードする

Visual Studioが言う:「i0uu5bcn.vhy」が読み込まれました。 PDBファイルを見つけたり開くことができません。

ブレークポイントは、次のように使用すると機能します。System.Diagnostics.Debugger.Break();

public static string[] Init(string scriptPath, params object[] parameters) 
     { 
      List<string> errors = new List<string>(); 

      SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(File.ReadAllText(scriptPath), null, scriptPath); 

      SyntaxTree encoded = CSharpSyntaxTree.Create(syntaxTree.GetRoot() as CSharpSyntaxNode, null, scriptPath, System.Text.Encoding.UTF8); 

      string assemblyName = Path.GetRandomFileName(); 

      MetadataReference[] references = new MetadataReference[] 
      { 
       MetadataReference.CreateFromFile(typeof(object).Assembly.Location), 
       MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location) 
      }; 

      CSharpCompilation compilation = CSharpCompilation.Create(
       assemblyName, 
       syntaxTrees: new[] { encoded }, 
       references: references, 
       options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); 

      Assembly finalAssembly = null; 

      using (var symbols = new MemoryStream()) 
      { 
       using (var ms = new MemoryStream()) 
       { 
        EmitResult result = compilation.Emit(ms, symbols); 

        if (!result.Success) 
        { 
         IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic => 
          diagnostic.IsWarningAsError || 
          diagnostic.Severity == DiagnosticSeverity.Error); 

         foreach (Diagnostic diagnostic in failures) 
         { 
          errors.Add($"{diagnostic.Id}: {diagnostic.GetMessage()}"); 
         } 
        } 
        else 
        { 
         ms.Seek(0, SeekOrigin.Begin); 
         symbols.Seek(0, SeekOrigin.Begin); 

         finalAssembly = Assembly.Load(ms.ToArray(), symbols.ToArray()); 

         Type type = finalAssembly.DefinedTypes.First().AsType(); 
         object obj = Activator.CreateInstance(type); 
         type.InvokeMember("Init", 
          BindingFlags.Default | BindingFlags.InvokeMethod, 
          null, 
          obj, 
          parameters); 
        } 
       } 
      } 

      return errors.ToArray(); 
     } 

答えて

2

ファイルが実際にUTF8でエンコードされていることを確認してください。エンコーディングは、PDBを生成するときに使用されるハッシュ関数の入力バイトを取得するために使用されます。 Encoding.UTF8はファイルがBOMであることを前提としています。

あなたはSourceLinkを使用して生成したPDB(...最初のディスクに保存)からチェックサムをダンプすることができます

sourcelink checksums -p <pdbfile> 

あなたののハッシュに対してダンプでスクリプトファイルの値を比較することができますあなたがコードで計算するソースファイル。これらの2つが一致しない限り、Visual Studioのデバッガはスクリプトファイルを正しく取得しません。

また、SourceText.From(Stream, Encoding)を使用すると、detect the correct encodingfor youになります。

だから私の勘が正しければ、このようなSourceTreeを得ることが同様にあなたの問題を解決する必要があり

SyntaxTree encoded; 
using(var stream = File.OpenRead(scriptPath)) 
{ 
    SourceText text = SourceText.From(stream, Encoding.UTF8); 
    encoded = CSharpSyntaxTree.ParseText(text, null, scriptPath); 
} 
関連する問題