我试图向用户显示旧版和新版的版本号,然后复制新版本。当我在显示版本信息后尝试复制文件时,我收到以下异常
该进程无法访问文件“C:\ Auto TEC \ Common.dll”,因为它正由另一个进程使用。
以下是代码:
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);
}
}
}
如何从对象中卸载程序集信息?
答案 0 :(得分:4)
如果不卸载包含它的所有appdomains,就无法卸载单个程序集。所以你应该使用不同的appdomain foreach你的程序集。
更多信息:
答案 1 :(得分:1)
加载程序集后,无法卸载。
您有一个选项可以将字节复制到内存中,然后使用Assembly.Load(byte[]).
加载。您也可以使用FileVersionInfo
,这样更容易。
答案 2 :(得分:1)
一旦将程序集加载到AppDomain中,就无法卸载它。实现此目的的唯一方法是将程序集加载到单独的AppDomain中,然后卸载整个AppDomain。
只要在AppDomain中引用该程序集中的程序集或类型,它就会被加载到该AppDomain中而不会被释放。
答案 3 :(得分:1)
在.Net中,如果将程序集加载到与应用程序相同的AppDomain中,则无法卸载它(这包括仅加载它以进行反射)。如果您需要检查组件内部,我建议使用Mono.Cecil(http://www.mono-project.com/Cecil)。
答案 4 :(得分:0)
我想我没有及时回答这个问题,但我遇到了同样的问题,为了将来参考你只需要使用“FileVersionInfo.GetVersionInfo”
System.Diagnostics程序
就是这样,这个选项不会加载程序集只是它的信息,你可以替换文件。