我正在尝试编写一个监视文件夹的程序,当文件夹中的任何文件被更改/更新时,它必须将该文件复制到另一个文件夹。特别是我想用这个程序来复制dll文件。每当我使用VS构建项目时,都会创建dll,然后我希望我的程序将新生成的dll复制到另一个文件夹。
问题是,当我尝试复制文件时,我得到一个异常,说该进程无法访问该文件,因为它正由另一个进程使用。我知道这个异常意味着什么,我已经看到了关于如何修复它的答案(但在大多数情况下,答案假设开发人员也控制了其他进程)。在我的情况下,我无法控制使用该文件的其他进程(可能是VS?)。
甚至有可能实现这一目标吗?如果没有,那么为什么我能够手动将该DLL复制到另一个文件夹但不能以编程方式执行。这是我用来复制文件的代码。
private void CopyFile(object sender, FileSystemEventArgs e)
{
string fileName = e.FullPath;
try
{
System.Threading.Thread.Sleep(5000);
File.Copy(fileName, System.IO.Path.Combine(DestinationFolderPath, fileName), true);
this.Dispatcher.Invoke(() =>
{
Log.Text += "Copied " + e.Name + Environment.NewLine;
});
}
catch (IOException exception)
{
this.Dispatcher.Invoke(() =>
{
Log.Text += "Error copying file " + e.Name + " " + exception.Message + Environment.NewLine;
});
}
}
答案 0 :(得分:3)
您应该激活DLL的卷影复制。在此处阅读更多内容:https://docs.microsoft.com/en-us/dotnet/framework/app-domains/shadow-copy-assemblies
实际上,当您启用卷影复制时(通过将ShadowCopyFiles属性设置为字符串值" true"),应用程序路径中的所有程序集将在加载之前复制到下载缓存中。然后,您可以从缓存文件夹中复制程序集 - 那些未被锁定的程序集。
这有帮助吗?
答案 1 :(得分:1)
如果一个文件是由另一个应用程序专门打开的,那么除了使用有点复杂的磁盘卷影副本并且它可能不会返回最新版本的文件之外,你几乎无法解决任何问题。
假设您没有创建备份应用程序,而是使用某种工具。如果您可能希望在合理的时间内监视创建文件的其他应用程序是免费的,那么您需要做的就是保留一个失败的应对操作列表,并在稍微延迟后重试它们。
如果您是为某个应用程序(例如VS)执行此操作,那么使用Post Build事件可能会更好,您可以找到项目设置。对于其他应用程序,您可以监视退出代码或其他内容以查找处理完文件的时刻,以便您可以自由复制它们。
答案 2 :(得分:0)
你可能会更加微妙;而不是使用File.Copy帮助器方法,您可以尝试打开文件流,以便使用允许打开多个读取流的共享参数显式读取。如果文件未打开以进行写入(并且DLL可能不会被打开以进行写入,除非它被更新,在这种情况下复制它将毫无意义)这允许您复制另一个进程打开的文件。
您可以使用标记FileStream.Open
和FileAccess.Read
FileShare.ReadWrite
将文件内容复制到另一个文件(目标)的文档