我正在尝试编写一个应用程序,将我创建的副本和安装程序编写到提供的计算机列表中。它在输入中只有一个计算机名称是完美的,但当我添加两个或更多时,它告诉我它无法从源文件中读取,因为它正在使用中。
更新: 如果这只是一个失败的原因,我愿意采取其他方法来完成这项工作。我的最终目标是尽可能快地将同一文件复制到数据中心的500台计算机。然后在每台计算机上执行该文件。现在执行我正在使用psexec -s所以我可以绕过UAC。
/*Button Click Code Below*/
/*Install for specific OS*/
foreach (string line in txtServers.Lines)
{
machine = line;
lbOutput.Items.Add("Preparing to copy files....");
/*Copy Files*/
if(!tWorker.IsAlive)
tWorker.Start();
lbOutput.Items.Add("File Copy Complete! Executing installer....");
}
/*File Copy Code Below*/
try
{
File.Copy("Ionic.Zip.Reduced.dll",@"\\"+machine+@"\C$\Temp\Ionic.Zip.Reduced.dll",true);
File.Copy("v5.32bit.Install.exe", @"\\" + machine + @"\C$\Temp\v5.32bit.Install.exe", true);
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
答案 0 :(得分:2)
神奇的词是FileShare.Read
:
using(var inputFile = new FileStream(
"oldFileName.txt",
FileMode.Open,
FileAccess.Read,
FileShare.Read))
{
using (var outputFile = new FileStream("newFileName.txt", FileMode.Create))
{
var buffer = new byte[0x10000];
int bytes;
while ((bytes = inputFile.Read(buffer, 0, buffer.Length)) > 0)
{
outputFile.Write(buffer, 0, bytes);
}
}
}
然后你应该能够复制它,即使有多个线程。
答案 1 :(得分:2)
另一种解决方法是将文件缓存在内存中....
类似
var filesToLoad = new[] {"a.txt", "b.txt"}.ToList();
var files = new Dictionary<string, byte[]>();
filesToLoad.ForEach(f => files.Add(f, File.ReadAllBytes(f)))
然后当你想写它们时
files.Keys.ToList()
.ForEach(f => File.WriteAllBytes(Path.Combine(machinePath, f), files[f]));
答案 2 :(得分:0)
如果您未指定COPY_FILE_OPEN_SOURCE_FOR_WRITE
标记,则可以通过调用CopyFileEx来执行此操作。
几年前我为CopyFileEx
发布了一个C#包装器。见A better File.Copy replacement。我不知道它是否会做你想要的(允许多个线程打开文件),但它可能值得一试。
答案 3 :(得分:0)
好的,所以在经历了一个非常沮丧的夜晚之后,似乎我需要一些睡眠来解决这个问题。
我最初在按钮点击事件中做了我的foreach,因为我在那个foreach中开始了一个线程,它只是继续而不管其他一切的状态。我已经把那个foreach移到了线程上,问题就解决了。我现在可以立即复制到多个位置,我必须说它非常快。
感谢大家一如既往的帮助!