CopyFileEx“参数无效”错误

时间:2012-04-27 16:39:27

标签: c# .net winapi copy

我正在编写一个(相当)简单的C#应用​​程序,使用.NET 4在运行可执行文件之前检查更新。如果网络共享上存在较新版本的exe,只需将其复制到本地文件夹并启动它。它完全正常工作,除了在阅读File.Copy()的限制时,我意识到在我这样做的时候我不能显示进度条,而且我看到的所有内容都说使用CopyFileEx,所以我试图这样做。

我使用了here找到的示例代码并且它编译得很好(尽管我仍然不确定背景工作者是如何发挥作用的),除非我实际去运行应用程序, CopyFilEx()方法返回false,错误为"参数不正确"。

我的代码(仅限相关部分,如果需要,我会添加更多内容)

调用该函数:

XCopy.Copy(strServerAppPath + strExeName, strLocalAppPath + strExeName, true, true, (o,    pce) =>
{
worker.ReportProgress(pce.ProgressPercentage, strServerAppPath + strExeName);
});

(源路径评估为" C:\ test.txt"目标路径为" C:\ test \ test.txt")

上面链接的代码中出现错误:

bool result = CopyFileEx(Source, Destination, new CopyProgressRoutine(CopyProgressHandler), IntPtr.Zero, ref IsCancelled, copyFileFlags);
            if (!result)
                throw new Win32Exception(Marshal.GetLastWin32Error());

在此先感谢您的帮助,我现在几个小时都在努力...

2 个答案:

答案 0 :(得分:3)

而不是处理所有那些编组,只需要“滚动你自己的”复印机就可以了解大块:

private static void CopyFile(string source, string destination, int bytesPerChunk)
{
    int bytesRead = 0;

    using (FileStream fs = new FileStream(source, FileMode.Open, FileAccess.Read))
    {
        using (BinaryReader br = new BinaryReader(fs))
        {
            using (FileStream fsDest = new FileStream(destination, FileMode.Create))
            {
                BinaryWriter bw = new BinaryWriter(fsDest);
                byte[] buffer;

                for (int i = 0; i < fs.Length; i += bytesPerChunk)
                {
                    buffer = br.ReadBytes(bytesPerChunk);
                    bw.Write(buffer);
                    bytesRead += bytesPerChunk;
                    ReportProgress(bytesRead, fs.Length);  //report the progress
                }
            }
        }
    }
}

答案 1 :(得分:3)

不是调用ReadBytes(),而是在每次调用时分配一个新的byte[]缓冲区数组,而是分配一个缓冲区(大小为64KB)并调用Read(buf, 0, buf.Length),这将读取数组中最多buf.Length个字节,然后返回读取的实际字节数。然后为每次读取重复使用相同的缓冲区数组(在将其内容写入目标流之后)。这样就不必为每次读/写操作重新分配新的缓冲区。

示例

例如,流复制方法的内部循环看起来像这样:

byte[]  buf;

// Allocate an I/O data buffer
buf = new byte[64*1024];

// Copy the contents of the input stream to the output stream
for (;;)
{
    int     len;

    // Read a block of data from the input stream
    len = inp.ReadBytes(buf, 0, buf.Length);
    if (len <= 0)
        break;

    // Write the data to the output stream
    outp.Write(buf, 0, len);
}

循环从输入流读取最多64KB的字节到缓冲区,然后写出读取到输出流的实际字节数。每个读/写操作使用相同的缓冲区,因此我们不会对缓冲区进行不必要的分配和解除分配。当读取操作失败时,我们已到达输入流的末尾,因此我们退出循环。