[.NET]找出那些組件參考到某一個組件

要從一堆程式中找出有參考到某件組件要如何做呢?

最近因為某些程式使用到某個舊的組件而發生錯誤,因為程式有蠻多支的,所以可以寫個程式來將有參考到的程式找出來修正。

所以參考「Determining .NET Assembly and Method References」,寫了支程式來掃描,畫面如下,

image

 

所以輸入要掃描的目錄及被參考的組件名稱,按下「開始掃描」就可以了,程式如下,


//記錄資訊的Class
internal class Info
{
	public string name;
	public int level;
	public string fileName;

	public Info(string name, int level, string fileName)
	{
		this.name = name;
		this.level = level;
		this.fileName = fileName;
	}
}

 


//開始掃描的Code
private void btnScan_Click(object sender, EventArgs e)
{
	string refAssemblyFileName = txtRefAssemblyPath.Text.Trim();

	if (refAssemblyFileName.Length == 0)
	{
		MessageBox.Show("Please Input Ref Assembly Name!");
		return;
	}
	string refAssemblyName = Path.GetFileNameWithoutExtension(refAssemblyFileName);
	string scanPath = txtScanPath.Text.Trim();
	if (scanPath.Length == 0)
	{
		MessageBox.Show("Please Input Scan Assembly Path!");
		return;
	}
	StringBuilder usingFiles = new StringBuilder();
	var searchFiles = from f in new DirectoryInfo(scanPath).GetFiles()
					  where f.Extension.EndsWith("EXE", true, null) ||
							f.Extension.EndsWith("DLL", true, null)
					  select f;
	foreach (var fileInfo in searchFiles)
	{
		ArrayList listFound = new ArrayList(); // list of Assembly names to avoid dups and an endless loop
		System.Collections.Stack stack = new System.Collections.Stack(); // stack of Assembly Info objects
		Info info = null;
		int level = 0;
		// store root assembly (level 0) directly into results list
		Assembly assembly;
		try
		{
			assembly = Assembly.LoadFrom(fileInfo.FullName);
		}
		catch (Exception ex)
		{
			Console.WriteLine(ex.ToString());
			continue;
		}

		info = new Info(assembly.ToString(), level, fileInfo.Name);

		bool isUsing = false;
		// seed level 1 assemblies onto Stack
		AssemblyName[] an = assembly.GetReferencedAssemblies();
		++level;
		for (int i = an.Length - 1; i >= 0; --i) // store level 1 Assemblies "right-to-left"
		{
			listFound.Add(an[i].ToString()); // record we've hit the assembly
			info = new Info(an[i].ToString(), level, an[i].Name);
			stack.Push(info);
			if (string.Compare(an[i].Name, refAssemblyName, StringComparison.CurrentCultureIgnoreCase) == 0)
			{
				isUsing = true;
			}
		}

		// do a preorder, non-recursive traversal to store all remaining assemblies
		while (stack.Count > 0 && !isUsing)
		{
			info = (Info) stack.Pop(); // get next assembly info
			++level;
			string subAssemblyPath = Path.Combine(scanPath, info.fileName);
			if (File.Exists(subAssemblyPath))
			{
				Assembly child = Assembly.LoadFrom(subAssemblyPath);
				AssemblyName[] subchild = child.GetReferencedAssemblies();
				for (int i = subchild.Length - 1; i >= 0; --i) // "right-to-left" = preorder traversal
				{
					if (!listFound.Contains(subchild[i].ToString()))
					{
						listFound.Add(subchild[i].ToString());
						Info subChildInfo = new Info(subchild[i].ToString(), level, subchild[i].Name);
						stack.Push(subChildInfo);
					}
				}
			}
		} // while
		if (isUsing)
		{
			usingFiles.Append(fileInfo.Name);
			usingFiles.Append(Environment.NewLine);
		}
	}
	txtUsingAssembly.Text = usingFiles.ToString();
}

 

原始檔

 

參考資料

Determining .NET Assembly and Method References

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^