1,现象:
在开发应用过程中如果引用其他类库,最后完成编译时将生成该类库的dll文件。如果引用多个类库,将生成多个dll文件,如此影响到后期类库被其他应用引用的简洁性。
2,合并多个dll:
通过微软的ILMerge工具将多个dll合并为一个dll,可大大的增加简洁性。但ILMerge软件需要进行安装且需要结合DOS命令使用,较为繁琐难记。故进行简单UI包装,使用ILMerge提供的接口开发了基于C#完成多个dll合并的winform程序。
3,效果
4,代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ILMerging;
using System.IO;
using System.Threading.Tasks;
namespace ILMergeGUI
{
public partial class MainForm : Form
{
private ILMerge merge;
public MainForm()
{
InitializeComponent();
merge = new ILMerge();
}
private void MainForm_Load(object sender, EventArgs e)
{
}
private void btnView_Click(object sender, EventArgs e)
{
OpenFileDialog openDlg = new OpenFileDialog();
openDlg.Filter = "(*.exe,*.dll)|*.exe;*.dll";
if (openDlg.ShowDialog() == DialogResult.OK)
{
this.txtMainAsm.Text = openDlg.FileName;
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
OpenFileDialog openDlg = new OpenFileDialog();
openDlg.Filter = "(*.exe,*.dll)|*.exe;*.dll";
openDlg.Multiselect = true;
if (openDlg.ShowDialog() == DialogResult.OK)
{
foreach (var fileName in openDlg.FileNames)
{
ListBoxItem item = new ListBoxItem();
item.FullFileName = fileName;
item.DisplayName = System.IO.Path.GetFileName(fileName);
this.listBox.Items.Add(item);
}
}
}
private void btnRemove_Click(object sender, EventArgs e)
{
if (this.listBox.SelectedItem != null)
{
this.listBox.Items.Remove(this.listBox.SelectedItem);
}
}
private void btnViewOutPath_Click(object sender, EventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.Description = "请选择和并后的导出路径";
dialog.ShowNewFolderButton = true;
if (dialog.ShowDialog() == DialogResult.OK)
{
this.txtOutPath.Text = dialog.SelectedPath;
}
}
private bool IsValidateInput()
{
if (string.IsNullOrEmpty(txtMainAsm.Text))
{
MessageBox.Show("主文件必填!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
if (listBox.Items.Count == 0)
{
MessageBox.Show("请选择引用程序集文件!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
if (string.IsNullOrEmpty(txtOutPath.Text))
{
MessageBox.Show("输出文件路径必填!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
if (string.IsNullOrEmpty(txtOutFileName.Text))
{
MessageBox.Show("输出文件必填!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
return true;
}
private void btnMerge_Click(object sender, EventArgs e)
{
if (!IsValidateInput())
{
return;
}
merge.Log = this.chkLog.Checked;
merge.LogFile = Path.Combine(Application.StartupPath, "log.txt");
List<string> lstInputFiles = new List<string>();
string primaryInputFile = this.txtMainAsm.Text;
lstInputFiles.Add(primaryInputFile);//The first element of the array is considered to be the primary assembly.
foreach (ListBoxItem item in this.listBox.Items)
{
lstInputFiles.Add(item.FullFileName);
}
merge.SetInputAssemblies(lstInputFiles.ToArray());
string outPutfile = Path.Combine(txtOutPath.Text, txtOutFileName.Text);
FileInfo fiPrimeray = new FileInfo(primaryInputFile);
string ext = fiPrimeray.Extension;
FileInfo fi = new FileInfo(outPutfile);
if (string.IsNullOrEmpty(fi.Extension))
{
outPutfile += ext;
fi = new FileInfo(outPutfile);
}
merge.OutputFile = outPutfile;
string targetPlatform = "v4";
foreach (Control ctrl in groupBox2.Controls)
{
RadioButton rdo = ctrl as RadioButton;
if (rdo != null && rdo.Checked)
{
targetPlatform = rdo.Text;
break;
}
}
merge.SetTargetPlatform(targetPlatform, string.Empty);
merge.TargetKind = ILMerge.Kind.SameAsPrimaryAssembly;
Task.Run(() =>
{
this.BeginInvoke(new Action(() =>
{
progressBar1.Visible = true;
}));
merge.Merge();
this.BeginInvoke(new Action(() =>
{
progressBar1.Visible = false;
MessageBox.Show("合并完成!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}));
});
}
}
}
internal class ListBoxItem
{
public string DisplayName
{
get;
set;
}
public string FullFileName
{
get;
set;
}
public override string ToString()
{
return DisplayName;
}
}
注明:
using ILMerging;
是对微软ILMerge.exe的引用