2011-10-28 208 views
3

我最近在正確發現c#中的應用程序根路徑時遇到了一些問題。我希望我的應用程序使用在下列情況下,正確的文件夾:在調試(視覺工作室)應用程序根路徑

  • Web應用程序中發佈
  • Web應用程序
  • 部署Web應用程序
  • 在調試
  • 控制檯應用程序
  • 控制檯應用程序版本
  • 部署控制檯應用程序
  • Windows服務(與控制檯應用程序非常相似)

即我需要這個在所有這些類型的應用程序共享的日誌程序集。它使用log4net,它需要在內部正確解析物理路徑 - 內部日誌組件。

因爲log4net需要調用BasicConfiguration.Configure從web.config/app.config加載它。問題在於它沒有設置文件觀察器,因此不會監視更改。解決方案是分別有一個log4net.config文件。

現在,我不喜歡將東西放在bin,bin/debug或bin/release文件夾中,因爲它永遠不會包含在源代碼管理中。取而代之的是,我在應用程序根目錄下有一個Config文件夾。所以你最終得到〜\ Application \ Config \ log4net.config。

在靜態記錄儀有2種方法:

public static string GetRootPath() 
    { 
     var debugPath = string.Empty; 
     #if (DEBUG) 
     debugPath = "..\\..\\"; 
     #endif 
     return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, debugPath); 
    } 

    public static void Init(string loggerName) 
    { 
     LoggerName = loggerName; 
     XmlConfigurator.Configure(new FileInfo(Path.Combine(GetRootPath(), "Config\\log4net.config"))); 
    } 

所以,你可以叫Logger.Init()中的Application_Start或內部的Main()用於控制檯應用程序。這適用於控制檯應用程序,但不適用於Web應用程序,因爲AppDomain.CurrentDomain.BaseDirectory指向Web應用程序root並且不指向它的bin文件夾(它也沒有調試或發行版)。

有沒有人有一個可靠的方法來解決所有以上要求的根路徑?那麼 - GetRootPath應該做什麼? PS:我知道我可以檢查是否(HttpContext.Current!= null),那麼不要合併調試路徑,但必須有更優雅的方式嗎?

回答

1

您可以使用Assembly類的CodeBase屬性來確定執行的程序集的路徑:

public static string GetRootPath() 
{ 
    var debugPath = string.Empty; 
    #if (DEBUG) 
    debugPath = "..\\..\\"; 
    #endif 
    return Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase).LocalPath), debugPath); 
} 

注意,對於Web應用程序和窗口服務的文件路徑是文件URI方案格式。因此,我使用Uri類將路徑轉換爲標準Windows路徑格式。

希望,這有助於。

+0

這段代碼有兩個問題:1:它將返回Web應用程序的應用程序根目錄以上一級目錄,2:如果您使用此目錄安裝程序集到GAC中或將它安裝在系統目錄中,它將返回錯誤的路徑Assembly.GetExecutingAssembly()返回程序集,您可以從中調用此代碼。 –

+0

好吧,我可以依靠日誌程序集總是使用它的應用程序的一部分,並部署在同一個文件夾中。至於Web應用程序的根,我已經添加了一個檢查,如果(HttpContext。Current == null),那麼路徑後綴會上升到兩個目錄(控制檯應用程序),否則只有一個目錄(調試模式下的Web應用程序)。因爲這個建議對我有幫助,所以標記爲答案。 –

+0

@Ales Potocnik Hahonina:是的,對於安裝到GAC中的組件,上述解決方案將無法工作。如果不使用HttpContext類,我無法想到另一種解決方案。 – Hans

相關問題