C#:为什么我的应用程序没有关闭其文件句柄?

时间:2009-08-09 02:19:54

标签: c# reflection assemblies

我有一个应用程序,它在文件系统和GAC中打开一系列DLL,并锁定这些文件。如何显式释放这些句柄,以便我可以在Visual Studio中重建它们而不关闭我的应用程序?

代码如下:

private void BuildTabPage_AssemblyTree(string filename, string foldername)
{
    Assembly assembly;
    try
    {
    assembly = Assembly.LoadFrom(filename);
    }
    catch (Exception ex) 
    {
    MessageBox.Show("Error loading assembly " + filename + "\n" + ex.Message);
    return;
    }
    TreeNode tRoot = BuildNode(assembly, foldername);
    tvAssemblies.Nodes.Add(tRoot);
    tvAssemblies.ExpandAll();

    txtResults.Text =
    RefsFound.ToString() + " References Located in Filesystem\r\n" +
    RefsInFramework.ToString() + " References Located in Framework\r\n" +
    RefsInGac.ToString() + " References Located in GAC\r\n" +
    RefsNotFound.ToString() + " References Not Found: \r\n\r\n";
    foreach (string s in MissingFiles)
    txtResults.Text += s + "\r\n";
}

private TreeNode BuildNode(Assembly assembly, string foldername)
{
    TreeNode tn = new TreeNode(assembly.GetName().Name);
    tn.ToolTipText = assembly.FullName + "\n" + assembly.CodeBase;
    AssemblyName[] assemblies = assembly.GetReferencedAssemblies();

    foreach (AssemblyName a in assemblies)
    {
    string filename2 = foldername + a.Name + ".dll";
    TreeNode tn2;
    if (System.IO.File.Exists(filename2))
    { // File found in folder
        RefsFound++;
        Assembly assy = Assembly.LoadFile(filename2);
        tn2 = BuildNode(assy, foldername);
    }
    else if (a.Name.StartsWith("System"))
    { // Framework assemblies not included
        RefsInFramework++;
        tn2 = new TreeNode();
        tn2.Text = a.Name;
        tn2.ForeColor = System.Drawing.Color.Green;
        tn2.ToolTipText += "\n.NET Framework File";
    }
    else
    {
        try
        {   // Find file in GAC
        Assembly assy = Assembly.Load(a);
        tn2 = new TreeNode(a.Name);
        tn.ToolTipText = assembly.FullName + "\n" + assembly.CodeBase + "\nFile detected in GAC";
        tn2.Text = "(" + filename2.Substring(filename2.LastIndexOf("\\") + 1) + ")";
        tn2.ForeColor = System.Drawing.Color.Green;
        RefsInGac++;
        }
        catch (System.IO.FileNotFoundException)
        {   // File not Found
        RefsNotFound++;
        if (!MissingFiles.Contains(a.Name))
            MissingFiles.Add(a.Name);
        tn2 = new TreeNode();
        tn2.Text = "(" + filename2.Substring(filename2.LastIndexOf("\\") + 1) + ")";
        tn2.ToolTipText = "File Not Found";
        tn2.ForeColor = System.Drawing.Color.Red;
        }
    }
    tn.Nodes.Add(tn2);
    }

    return tn;
}

3 个答案:

答案 0 :(得分:6)

不幸的是,在应用程序退出之前,不会卸载加载到默认AppDomain的程序集。但是,您可以在创建的AppDomain中创建AppDomain并加载程序集。卸载创建的AppDomain时,将在已创建的AppDomain中加载的程序集将一起卸载。

答案 1 :(得分:1)

将装配加载到流程后,无法卸载。您可以为要加载的每个程序集创建应用程序域,获取程序集属性,然后关闭应用程序域。

答案 2 :(得分:0)

我认为如果您将AppDomain设置为使用ShadowCopy,它应该可以工作:

http://blogs.msdn.com/junfeng/archive/2004/02/09/69919.aspx

此链接非常详细地处理您的问题(如果我理解正确的话):http://blogs.msdn.com/jasonz/archive/2004/05/31/145105.aspx