2010-11-12 37 views
2

我正在做一個幾乎已經完成的應用程序,但有一件事正在困擾着我。有大約12-13個文件必須位於該文件夾的目錄(某些.dlll,某些.xml文件等)中,以便應用程序運行,並且我想讓我的應用程序儘可能緊湊,這意味着我需要更少的文件與應用程序一起使用。所以我的問題是,我該怎麼做?所有的文件都可以包含在應用程序本身中嗎? .dll是否需要在應用程序文件夾中,或者我可以從其他地方引用它們?我正在考慮爲所有這些文件創建一個文件夾,但是如果.dll文件沒有放在與應用程序相同的目錄中,我認爲我的應用程序不會運行。引用文件

+1

如果轉到個人檔案頁面,您會看到許多沒有被接受答案的問題。 (答案數爲白色而不是黃色的答案)。在每個問題中,點擊最有幫助的答案旁邊的空白檢查。 – SLaks 2010-11-12 03:58:37

回答

0

How to embed and access resources by using Visual C#看起來就是你所需要的。
[編輯] 如果要加載的DLL,你可以在上面結合與AppDomain.AssemblyResolve事件SLaks提到這樣的:

using System.IO; 
using System.Reflection; 

namespace ConsoleApplication3 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     AppDomain currentDomain = AppDomain.CurrentDomain; 
     currentDomain.AssemblyResolve += 
       new ResolveEventHandler(MyResolveEventHandler); 
     var myWrappedClass1 = 
      currentDomain.CreateInstance(
        "ConsoleApplication3.ClassLibrary1.dll", 
        "ClassLibrary1.Class1"); 
     var myClass1 = myWrappedClass1.Unwrap(); 
     Console.WriteLine(myClass1.GetType().InvokeMember(
        "Add", 
        BindingFlags.Default | BindingFlags.InvokeMethod, 
        null, 
        myClass1, 
        new object[] { 1, 1 })); 
     Console.ReadLine(); 
    } 

    private static Assembly MyResolveEventHandler(
      object sender, ResolveEventArgs args) 
    { 
     Assembly currentAssembly=null; 
     Stream dllStream; 
     try 
     { 
      currentAssembly = Assembly.GetExecutingAssembly(); 
      dllStream = 
        currentAssembly.GetManifestResourceStream(args.Name); 
      var length = (int)dllStream.Length; 
      var dllByteArray = new byte[length]; 
      int bytesRead; 
      int offset = 0; 
      while ((bytesRead = dllStream.Read(
            dllByteArray, 
            offset, 
            dllByteArray.Length - offset)) 
        > 0) 
       offset += bytesRead; 
      return Assembly.Load(dllByteArray); 
     } 
     catch 
     { 
      Console.WriteLine("Error accessing resources!"); 
     } 
     return null; 
    } 
    } 
} 

其中Class1是一個只包含一個類庫:

namespace ClassLibrary1 
{ 
    public class Class1 
    { 
     public int Add(int x, int y) 
     { 
      return x + y; 
     } 
    } 
} 

並將DLL作爲嵌入式資源添加到文件中:

alt text alt text

+0

如果他們提供的示例不夠流暢,請告訴我您在開發什麼.NET版本,並且會爲您提供一些示例代碼。 – 2010-11-12 03:57:30

+0

你也可以使用.DLL文件做到這一點嗎?我確實知道你可以用這種方式嵌入資源,但是右鍵單擊並選擇.dll文件的屬性時,屬性中不會顯示任何內容。另外,我正在使用.NET Framework 4.0 – david 2010-11-12 04:21:35

+0

大衛您好,請讓我知道這個例子是否更清晰。 – 2010-11-13 02:46:10

2

您可以處理AppDomain.AssemblyResolve event,並呼籲Assembly.Load(path)從非標準文件夾加載的DLL。

你甚至可以調用Assembly.Load(byte[])加載嵌入EXE中的DLL作爲資源。

請注意,JITter會在方法開始執行之前(爲了編譯方法)加載方法使用的所有類型。
因此,必須在使用DLL中的任何方法或類型之前添加事件處理程序,並且添加處理程序的方法不能直接使用DLL。

+0

感謝您的信息!我還沒有玩過AssemblyResolve賽事,但我現在看到了我的週末項目將會是什麼。 :-) – 2010-11-12 04:15:58

0

聽起來像你可以使用Embedded Resources這部分(所有非DLL)。編譯後,您可以使用ILMerge來合併您的程序集,但ILMerge有一些限制...