2013-12-19 24 views
1

這是我的問題。我想在運行時將庫加載到我的應用程序中。這將允許應用程序消耗接口的新實現而不需要重新編譯。應用程序將搜索它自己的目錄中的庫。我有這樣的代碼:確定服務器或客戶端上的應用程序執行目錄

var path = Assembly.GetExecutingAssembly().Location; 
path = Path.GetDirectoryName(path); 
path = Path.Combine(path, "<my assembly>.dll"); 

var assembly = Assembly.LoadFile(path); 

此代碼在單元測試中完美工作。但是,該應用程序是一個Web應用程序。當我將這段代碼作爲應用程序的一部分運行時,Assembly.GetExecutingAssembly().Location在.net框架中返回一個臨時目錄。 (C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Temporary ASP.NET Files \ ...)我大概可以通過使用Server.MapPath來解決這個問題,但是代碼將不再是單元可測試的。

我真的很想找到能夠以平臺無關的方式給我執行目錄的東西,也就是說,它在單元測試和Web應用程序中搜索正確的目錄。

我已經試過:

Assembly.GetExecutingAssembly().Location //Works as a test but not on a server 
Application.ExecutablePath //Not an executable, so this won't work 
System.AppDomain.CurrentDomain.BaseDirectory //Almost works in web app, but stops too early in the directory structure 
Environment.CurrentDirectory //returns system32 directory 
+0

GetCallingAssembly也當爲一個Web應用程序運行返回.NET Framework中的目錄。 – SouthShoreAK

回答

0

你可以用這樣的方法。它將返回裝配的實際位置。

public static string GetAssemblyLocation(Assembly assembly) 
{ 
    if (assembly.IsDynamic) 
    { 
     return null; 
    } 

    string codeBase = assembly.CodeBase; 
    UriBuilder uri = new UriBuilder(codeBase); 

    string path = Uri.UnescapeDataString(uri.Path); 
    path = Path.GetDirectoryName(path); 
    path += "\\" + Path.GetFileName(assembly.Location); 

    return path; 
} 

CodeBase將返回程序集的原始位置。在Web應用程序的情況下,當所有程序集在臨時文件夾中都使用影子副本時,CodeBase仍將返回Bin文件夾中的路徑。但是使用協議,像這樣的文件:// c:/somesite/bin/sassembly.dll。所以這個方法只是獲取它並將其轉換爲通常的文件路徑。

1

這是我用過這兩個測試環境和Web應用程序下工作:

private static string AssemblyDirectory 
    { 
     get 
     { 
      string codeBase = Assembly.GetExecutingAssembly().CodeBase; 
      var uri = new UriBuilder(codeBase); 
      string path = Uri.UnescapeDataString(uri.Path); 
      return Path.GetDirectoryName(path); 
     } 
    } 
+0

Luke與Sergey Litvinov提供的答案有何不同? –

相關問題