2010-09-30 5 views
1

J'essaie d'afficher les numéros de version de l'ancien et du nouveau à l'utilisateur, puis copiez la nouvelle version. Quand je tentais copier le fichier après avoir affiché les informations de version que je reçois l'exception suivanteDisposing assembly

Le processus ne peut pas accéder au fichier « C: \ Auto TEC \ common.dll » parce qu'il est utilisé par un autre processus.

Voici le code:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.IO; 
using System.Reflection; 
using System.Diagnostics; 

namespace copyfile 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 


      string sourceDirectory = @"E:\newversion\Auto TEC"; 
      string targetDirectory = @"C:\Auto TEC"; 

      Copy(sourceDirectory, targetDirectory); 
      label3.Text = "sucess"; 
      loadAssembyNames(); 

     } 

     void f2_FormClosed(object sender, FormClosedEventArgs e) 
     { 
      this.Close(); 
     } 
     public static void Copy(string sourceDirectory, string targetDirectory) 
     { 
      DirectoryInfo diSource = new DirectoryInfo(sourceDirectory); 
      DirectoryInfo diTarget = new DirectoryInfo(targetDirectory); 

      CopyAll(diSource, diTarget); 


     } 

     public static void CopyAll(DirectoryInfo source, DirectoryInfo target) 
     { 
      // Check if the target directory exists, if not, create it. 
      if (Directory.Exists(target.FullName) == false) 
      { 
       Directory.CreateDirectory(target.FullName); 
      } 

      // Copy each file into it's new directory. 
      foreach (FileInfo fi in source.GetFiles()) 
      { 

       fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true); 
      } 

      // Copy each subdirectory using recursion. 
      foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()) 
      { 
       DirectoryInfo nextTargetSubDir = 
        target.CreateSubdirectory(diSourceSubDir.Name); 
       CopyAll(diSourceSubDir, nextTargetSubDir); 
      } 

     } 
     string _errMsg; 
     //private AssemblyInformation _info; 
     private void getfilenames(string directoryPath, int location) 
     { 
      string[] path = new string[25]; 
      int count = 0; 
      foreach (string file in System.IO.Directory.GetFiles(directoryPath)) 
      { 
       path[count] = file; 
       count++; 

      } 

      Assembly asm = null; 


       for (int i = 0; i < count; i++) 
       { 
        try 
        { 
         //asm = Assembly.LoadFrom(path[i]); 
         asm = Assembly.LoadFile(path[i]); 
         if (asm != null) 
         { 
          if (location == 1) 
          { 
           listBox1.Items.Add(asm.GetName().Name + asm.GetName().Version.ToString()); 

          } 
          else 
          { 
           listBox2.Items.Add(asm.GetName().Name + asm.GetName().Version.ToString()); 
          } 
         } 
        } 
        catch (Exception err) 
        { 
         this._errMsg = err.Message; 
        } 
       } 

       asm = null; 

       GC.Collect(); 

     } 



     private void Form1_Load(object sender, EventArgs e) 
     { 
      loadAssembyNames(); 

     } 

     private void loadAssembyNames() 
     { 
      listBox1.Items.Clear(); 
      listBox2.Items.Clear(); 
      getfilenames(@"C:\Auto TEC", 1); 

      getfilenames(@"E:\newversion\Auto TEC", 2); 
     } 
    } 
} 

Comment puis-je décharger les informations d'assemblage de l'objet?

+0

Dupliqué? Regardez ceci http://stackoverflow.com/questions/123391/how-to-unload-an-assembly-from-the-primary-appdomain – goenning

Répondre

4

Il est impossible de décharger un ensemble individuel sans décharger tous les domaines d'application qui le contiennent. Vous devriez donc utiliser un domaine différent pour chacun de vos assemblages.

Plus d'infos:

+1

si j'utilise AssemblyName.GetAssemblyName (chemin [i]); il ne charge pas l'assemblage. ça a marché pour moi. – hari

+0

merci pour votre réponse – hari

1

Une fois que l'assemblage est chargé, il ne peut pas être déchargé.

Vous avez une option pour copier les octets dans la mémoire, puis charger en utilisant Assembly.Load(byte[]). Aussi, vous pouvez utiliser FileVersionInfo qui est beaucoup plus facile.

1

Vous ne pouvez pas décharger un assemblage une fois chargé dans votre AppDomain. La seule façon d'effectuer cela est de charger l'assembly dans un AppDomain distinct et de décharger l'AppDomain entier.

Dès que vous référencez un assembly ou un type à partir de cet assembly dans votre AppDomain, il sera chargé dans ce AppDomain et non publié.

1

Dans .Net, si vous chargez l'assembly dans le même AppDomain que l'application, il n'est pas possible de le décharger (cela inclut le chargement pour la réflexion uniquement). Si vous devez inspecter les composants internes de l'assemblage, je recommande d'utiliser Mono.Cecil (http://www.mono-project.com/Cecil).

0

Je pense que je ne suis pas dans le temps de répondre à cette question, mais j'ai eu le même problème et pour référence ultérieure, vous avez juste besoin d'utiliser « FileVersionInfo.GetVersionInfo »

system.diagnostics

et thats it, cette option ne chargera pas l'assembly juste ses informations et vous pourrez remplacer le fichier.