代码之家  ›  专栏  ›  技术社区  ›  tsilb

C#:为什么我的应用程序不关闭它的文件句柄?

  •  1
  • tsilb  · 技术社区  · 15 年前

    代码如下:

    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 回复  |  直到 15 年前
        1
  •  6
  •   Chansik Im    15 年前

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

        2
  •  1
  •   Scott Stanchfield    15 年前

    一旦将程序集加载到进程中,就无法卸载它。相反,您可以为要加载的每个程序集创建应用程序域,获取程序集属性,然后关闭应用程序域。

        3
  •  0
  •   Jon    15 年前

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

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

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