要從一堆程式中找出有參考到某件組件要如何做呢?
最近因為某些程式使用到某個舊的組件而發生錯誤,因為程式有蠻多支的,所以可以寫個程式來將有參考到的程式找出來修正。
所以參考「Determining .NET Assembly and Method References」,寫了支程式來掃描,畫面如下,
所以輸入要掃描的目錄及被參考的組件名稱,按下「開始掃描」就可以了,程式如下,
//記錄資訊的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:從零開始的軟體開發生活」
請大家繼續支持 ^_^