C #: Почему мое приложение не закрывает свои файловые дескрипторы? - PullRequest
1 голос
/ 09 августа 2009

У меня есть приложение, которое открывает серию библиотек DLL в файловой системе и в GAC и блокирует эти файлы. Как я могу освободить эти дескрипторы явно, чтобы я мог перестроить их в 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 ]

6 голосов
/ 09 августа 2009

К сожалению, сборки, загруженные в домен приложения по умолчанию, не будут выгружены, пока приложение не закроется. Однако вы можете создать AppDomain и загрузить сборки в созданный AppDomain. Когда созданный AppDomain выгружен, сборки, загруженные в созданный AppDomain, будут выгружены вместе.

1 голос
/ 09 августа 2009

Как только вы загрузите сборку в свой процесс, вы не сможете ее выгрузить. Вместо этого вы можете создать домен приложения для каждой сборки, которую хотите загрузить, получить свойства сборок, а затем закрыть домен приложения.

0 голосов
/ 09 августа 2009

Я думаю, что если вы настроите свой AppDomain для использования ShadowCopy, он должен работать:

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

Эта ссылка подробно описывает ваш вопрос (если я вас правильно понимаю): http://blogs.msdn.com/jasonz/archive/2004/05/31/145105.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...