要如何由程式設定DLL參考目錄及Config File的位置?
讓執行目錄只有一個執行檔呢?
有朋友梅梅子問「如何改變執行時參考目錄?」,直覺想到可以設定在config中設定,可以參考「將共用的DLL放在同一個目錄之中」。
但這位朋友想要連config檔也移走,這樣程式執行起來就找不到設定檔了!
所以建立一個簡單的測試程式(Windows Form程式呼叫一個DLL的Class(ClassLibrary2.Class1),而該Class取得Config檔appSettings中某個項目值),來試看看!
ClassLibrary2.Class1的內容
namespace ClassLibrary2
{
public class Class1
{
public string ConfigAppsettingValue { get; set; }
public Class1()
{
string configValue = System.Configuration.ConfigurationManager.AppSettings["Test"];
ConfigAppsettingValue = configValue;
}
}
}
Windows Form程式(app.config)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="Test" value="Class Test"/>
</appSettings>
</configuration>
Windows Form程式(button的Click)
private void button1_Click(object sender, EventArgs e)
{
string configValue = System.Configuration.ConfigurationManager.AppSettings["Test"];
MessageBox.Show("ConfigValue:" + configValue);
ClassLibrary2.Class1 c1 = new ClassLibrary2.Class1();
MessageBox.Show("c1 ConfigValue:" + c1.ConfigAppsettingValue);
}
當exe, exe.config, dll都在同一個目錄下,運作都正常。如下,
可是如果將除了exe之外的檔案都搬到files的子目錄之中,程式就會發生錯誤!
想說可以透過AppDomain.CurrentDomain.SetupInformation.ConfigurationFile來指定config檔,如下,
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile="myCustConfigFile";
但卻沒有效果!
後來有找到使用 AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "myCustConfigFile") 可以改變Config檔的位置,而在config檔中加入 probing 的設定。
執行程式,還是會出現DLL找不到的錯誤!
看來還是要在程式中指定才PrivatePath才行!
所以就在 Main() Method中多設定 PrivatePath ,如下,
static void Main()
{
string custFolderName = @"files";
string configFile = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), custFolderName, Path.GetFileName(Application.ExecutablePath) + ".config");
if (File.Exists(configFile) == true)
{
//檔案存在才執行
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", configFile);
AppDomain.CurrentDomain.AppendPrivatePath(custFolderName);
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
那如果您使用的是VB.NET那段程式碼要加在那裡呢?
您可以新增一個Module如下,
Module App
<STAThread()> _
Public Sub Main()
Dim custFolderName As String = "files"
Dim configFile As String = Path.Combine(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), custFolderName), Path.GetFileName(Application.ExecutablePath) & ".config")
If File.Exists(configFile) Then
'檔案存在才執行
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", configFile)
AppDomain.CurrentDomain.AppendPrivatePath(custFolderName)
End If
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New Form1())
End Sub
End Module
然後在專案屬性中設定啟動的物件為Sub Main,如下,
設定完成後,重新建罝專案後就可以了哦!
註:朋友梅梅子有說可以在Form的New 建構子中去設定,但筆者測試起來雖然沒有問題,但是卻會有取不到config檔appSettings中的值,而在Sub Main()中測試則是沒問題的!
另外,「代码控制PrivateBinPath和ConfigurationFile的位置」這篇所使用的方式也是可以的! 只是Code比較長一點!
以上方式,希望對大家有所幫助,有更好的方式,也請讓我知道哦!
參考資料
代码控制PrivateBinPath和ConfigurationFile的位置
Relocating app.config file to a custom path
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^