經過大量的靈魂搜索,我設法收集了足夠的inspiration來撰寫以下代碼片段。這個想法是使用.pdb
文件來發現源代碼的位置。您需要參考ISymWrapper.dll
並以32位模式編譯。如果有更簡單的方法,我會很高興聽到它。
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-23 16:20:45
@ LasseV.Karlsen我需要它能夠在調試運行時重新編譯部分解決方案(這些部分是特定領域的語言)。我確信有些事情可以做到。我的第一個想法是解析.pdb,它顯然具有這些信息,但顯然它不容易分析。 – Gleno 2013-03-23 16:28:07