日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用ilmerge实现.net程序静态链接

發布時間:2025/3/21 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用ilmerge实现.net程序静态链接 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

當編寫規模稍大一點的程序時,需要進行模塊劃分。我們一般是對每個模塊建一個工程,輸出一個類庫,這樣就形成了一個exe加多個類庫的解放方案。這樣本身是沒有什么問題的,就是發布上稍微有點麻煩,需要發布一個exe加多個dll文件。特別是那些需要經常更新的程序,其實本身可能并不大,一共也就幾百kb,但每次還要發布三四個dll確實令人厭煩,做成安裝包就更沒必要了。

在C++中,我們一般可以通過靜態鏈接解決這種問題,但在.net中卻不行,每個類庫只能輸出dll,VisualStudio官方也沒有提供靜態鏈接的選項,其實從理論上講要想合并似乎也不難,ildasm能夠把.NET程序反編譯成il,那么把兩個il合并到一個il當中再用il編譯就可以了。雖然M$卻沒有直接提供這種功能,但M$的一位大牛提供了一個工具ILMerge可以實現這種功能,可以在http://research.microsoft.com/~mbarnett/ILMerge.aspx下載。

網上也有一些文章對這個工具進行了介紹,margiex的blog中的說明就介紹的較簡明扼要,這里轉錄一下:

ilmerge /ndebug /target:exe /targetplatform:v1.1 /out:newclient.exe oldclient.exe /log AutoUpdater.dll DockingSuite.dll DocumentManager.dll FileHelpers.dll OutlookBar.dll SandBar.dll ICSharpCode.SharpZipLib.dll

解釋如下:

  • target: 指定輸出組件的類型,有DLL/EXE/WINEXE; (如果是EXE,則程序在執行的時候將出現一個DOS窗口(即使是WINFORM的程序). 因此應該設置target為winexe)
  • targetplatform: 輸出組件的.net運行版本;
  • out: 合并后的組件全名;
    后面是主要的被合并的組件名稱, 及相關所有的其它DLL;
    上面的示例只是合并為EXE, 也可以多個DLL合并成一個DLL使用, 各自的命名空間不會改變;
    • 不能合并interop這種由COM轉換過來的DLL; (可以合并,但相關依賴的DLL必須也一起合并, 第一次合并的時候只有Excel.dll,總是報錯,以為是interop的緣故,后來才發現是沒有合并vbide.dll的緣故,復制到目錄再一起合并,一切OK.)
    • 如果有資源DLL, 應該將要被合并的oldclient.exe先改為別的名稱,然后合并后的輸出命名為:oldclient.exe,因為資源文件名是:oldclient.resources.dll,而ILMERGE不能合并資源文件,否則在導出后將找不到此資源文件。(如果哪位知道如何合并資源文件,請指教,謝謝)
    • 雖然合并后的EXE比較大,但在用戶那里只有一個EXE,這樣直觀的多,也容易升級維護.

    原文地址:http://www.cnblogs.com/margiex/archive/2008/06/24/302329.html

    具體的詳細使用文檔請參看它的說明文檔,還是很簡單的。

    另外,也可以通過編程的方式來調用ILMerge的庫來實現簡化合并,這里轉錄一下CodeProject上的一篇文章Post build step static linking tool for C#, using ILMerge的代碼:

    Code
    using?System;
    using?System.Text;
    using?System.Collections;


    namespace?HTMerge
    {
    ????
    class?Program
    ????{???
    ????????
    static?void?Main(string[]?args)
    ????????{
    ????????????
    try
    ????????????{
    ????????????????String?strDir?
    =?"";
    ????????????????
    if?(args.Length?!=?1)
    ????????????????{
    ????????????????????Console.WriteLine(
    "Usage:?HTMerge?directoryName");
    ????????????????????
    return;
    ????????????????}
    ????????????????
    else
    ????????????????{
    ????????????????????strDir?
    =?args[0];
    ????????????????}

    ????????????????String[]?exeFiles?
    =?System.IO.Directory.GetFiles(strDir,?"*.exe");
    ????????????????String[]?dllFiles?
    =?System.IO.Directory.GetFiles(strDir,?"*.dll");

    ????????????????ArrayList?ar?
    =?new?ArrayList();

    ????????????????Boolean?bAdded?
    =?false;

    ????????????????
    //there?might?be?more?than?1?exe?file,?
    ????????????????
    //we?go?for?the?first?one?that?isn't?the?vshost?exe
    ????????????????foreach?(String?strExe?in?exeFiles)
    ????????????????{
    ????????????????????
    if?(!strExe.Contains("vshost"))
    ????????????????????{
    ????????????????????????ar.Add(strExe);
    ????????????????????????bAdded?
    =?true;
    ????????????????????????
    break;
    ????????????????????}
    ????????????????}

    ????????????????
    if?(!bAdded)
    ????????????????{
    ????????????????????Console.WriteLine(
    "Error:?No?exe?could?be?found");
    ????????????????????
    //I?know?multiple?returns?are?bad�
    ????????????????????return;
    ????????????????}

    ????????????????bAdded?
    =?false;

    ????????????????
    foreach?(String?strDLL?in?dllFiles)
    ????????????????{
    ????????????????????ar.Add(strDLL);
    ????????????????????bAdded?
    =?true;
    ????????????????}

    ????????????????
    //no?point?merging?if?nothing?to?merge?with!
    ????????????????if?(!bAdded)
    ????????????????{
    ????????????????????Console.WriteLine(
    "Error:?No?DLLs?could?be?found");
    ????????????????????
    //I?know?multiple?returns?are?bad�
    ????????????????????return;
    ????????????????}


    ????????????????
    //You?will?need?to?add?a?reference?to?ILMerge.exe?from?Microsoft
    ????????????????
    //See?http://research.microsoft.com/~mbarnett/ILMerge.aspx
    ????????????????ILMerging.ILMerge?myMerge?=?new?ILMerging.ILMerge();

    ????????????????String[]?files?
    =?(String[])ar.ToArray(typeof(string));

    ????????????????String?strTargetDir?
    =?strDir?+?"\\Merged";

    ????????????????
    try
    ????????????????{
    ????????????????????System.IO.Directory.CreateDirectory(strTargetDir);
    ????????????????}
    ????????????????
    catch
    ????????????????{
    ????????????????}

    ????????????????
    //Here?we?get?the?first?file?name?
    ????????????????
    //(which?was?the?.exe?file)?and?use?that
    ????????????????
    //?as?the?output
    ????????????????String?strOutputFile?=?System.IO.Path.GetFileName(files[0]);

    ????????????????myMerge.OutputFile?
    =?strTargetDir?+?"\\"?+?strOutputFile;
    ????????????????myMerge.SetInputAssemblies(files);

    ????????????????myMerge.Merge();
    ????????????}
    ????????????
    catch?(Exception?ex)
    ????????????{
    ????????????????Console.WriteLine(String.Format(
    "Error?:{0}",ex.Message));
    ????????????}

    ????????}
    ????}
    }

    另外,需要說明的是,這個工具目前支持的是.net 2.0,那些.net 3.0 3.5的程序由于是和.net2.0同一個clr,也可以使用(我試過的)。

    總結

    以上是生活随笔為你收集整理的使用ilmerge实现.net程序静态链接的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。