0

精巧なデバッグ シナリオを有効にするには、実行時にソース ファイルの場所を把握するためにアセンブリが必要です。

オブジェクトはこのAssembly情報を認識しておらず、おそらく認識すべきではありません。ファイルは明らかに知ってい.pdbますが、それを解析する方法がわかりません。したがって、ビルド時にアセンブリに属性をタグ付けできるのではないかと考えました。次のような効果があります。

[assembly: AssemblyMetadata("ProjectDirectory", $(ProjectDir))]

デバッグ中にIISによって一時ディレクトリに設定されるため、現在のディレクトリを使用できません。また、ディレクトリをハードコーディングしたくありません。

これを解決するためにこれまでに最も近いのは、Assembly.CodeBaseプロパティを使用することです。IIS ソリューションがビルドされたディレクトリ (Solution/IISProject/bin/Debug/ではなく/Solution/source/MyLibrary/) を指していますが、私のプロジェクト ディレクトリではありません。ハッキーなソリューションは、そこからいくつかのレベルを上げてから、いくつかのレベルを下げてプロジェクト フォルダーに戻ります。可能であれば、このハッキングを避けたいと思います。

4

2 に答える 2

0

通常、これらのタイプのシナリオを有効にするためのベスト プラクティスは、これらのディレクトリを web.config の設定に配置することです。したがって、特定の状況に基づいて、このディレクトリの代わりにこのディレクトリを使用すると言えます。多くの場合、if (IsDebugging) がこのディレクトリを使用し、そうでない場合はこのディレクトリを使用します。

于 2013-03-23T16:22:04.377 に答える
0

多くの魂の検索の後、私は次のスニペットを作成するのに十分なインスピレーションを集めることができました. .pdbこのファイルを使用して、ソース コードの場所を発見するという考え方です。ISymWrapper.dll32 ビット モードで参照およびコンパイルする必要があります。もっと簡単な方法があれば、それを聞いてうれしいです。

using System;
using System.Diagnostics.SymbolStore;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Linq;
public static class AssemblyDirectoryInfo
{
    private const string
        ImporterId = "7DAC8207-D3AE-4c75-9B67-92801A497D44",
        DispenserId = "809c652e-7396-11d2-9771-00a0c9b4d50c",
        DispenserClassId = "e5cb7a31-7512-11d2-89ce-0080c792e5d8";

    [Guid(ImporterId), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComVisible(true)]
    public interface IMetaDataImport{}

    [Guid(DispenserId), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComVisible(true)]
    interface IMetaDataDispenser
    {
        void DefineScope();

        void OpenScope([In, MarshalAs(UnmanagedType.LPWStr)] String szScope, [In] Int32 dwOpenFlags,
                       [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out Object punk);
    }

    [DllImport("ole32.dll")]
    private static extern int CoCreateInstance([In] ref Guid guid,
        [In, MarshalAs(UnmanagedType.IUnknown)] Object pUnkOuter,
        [In] uint dwClsContext,
        [In] ref Guid riid,
        [Out, MarshalAs(UnmanagedType.Interface)] out Object ppv);

    public static DirectoryInfo GetAssemblyCodeBase(Assembly assembly)
    {
        var file = new FileInfo(assembly.Location);

        Guid dispenserClassId = new Guid(DispenserClassId),
             importerIid = new Guid(ImporterId),
             dispenserIid = new Guid(DispenserId);

        object dispenser, importer;

        CoCreateInstance(ref dispenserClassId, null, 1, ref dispenserIid, out dispenser);
        ((IMetaDataDispenser)dispenser).OpenScope(file.FullName, 0, ref importerIid, out importer);

        var ptr = Marshal.GetComInterfaceForObject(importer, typeof(IMetaDataImport));
        var reader = new SymBinder().GetReader(ptr, file.FullName, file.DirectoryName);
        return reader.GetDocuments()
                     .Select(d => d.URL)
                     .Where(v => !string.IsNullOrEmpty(v))
                     .OrderBy(v => v.Length)
                     .Select(v => new FileInfo(v).Directory)
                     .First();
    }
}
于 2013-03-23T19:46:02.343 に答える