如果当前文件正在使用,如何打开文件的影子副本

7

我正在尝试备份服务器上的文件,但其中一些文件正在使用中,无法打开。相反,如果当前副本正在使用中,我想打开它们的影子副本。我该如何做到这一点?

供参考,我正在使用C# .net 3.5。

3个回答

9
这个问题已经相当老了,所以我的回答可能对你没有什么用处,但是作为一个问答网站,也许它仍然会对其他人有所帮助。
我不能/不想放下整个实现,但过程大致如下:
1. 通过卷影复制服务提供程序创建卷影副本,该卷影副本位于要读取文件的驱动器上(这在MSDN上有很好的文档,还有一个创建这些卷影副本的示例客户端,很可能对您足够)。 2. 要么创建一个持久性的卷影副本,要么使用“回调”机制(调用您的应用程序)。 3. 通过UNC路径和CreateFile打开所需的文件(UNC看起来像这样:\\?\GlobalRoot\Devices\HarddiskVolumeShadowCopyXZY\yourpath\yourfile.yourextension)。 4. 对文件进行任何操作。 5. 如果您创建了一个持久性的VSC,在完成后应使用示例客户端将其删除。
更多信息请参见此处:http://technet.microsoft.com/en-us/library/cc785914%28WS.10%29.aspx 和此处:http://msdn.microsoft.com/en-us/library/bb968832%28VS.85%29.aspx

2
问题在于.NET内置的文件管理工具无法访问\?\GlobalRoot指令。实际上,您必须降到winapi级别。有一个名为AlphaFSS的库可以做到这一点,但它存在一些主要问题。我曾经使用过它一段时间,但遇到了文件大小所需的两个DWORD表示其大小的问题,AlphaFSS只读取较低的DWORD。 - Malfist
我知道这是一个旧的帖子...但是.Net 4.62及以上版本确实支持\?\前缀。 - egray

2

如果您控制第一个进程,则可以指定文件句柄共享类型。

string contents1;
string contents2;
using (FileStream fs1 = new FileStream("test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    using (var tr1 = new StreamReader(fs1))
    {
        using (FileStream fs2 = new FileStream("test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (var tr2 = new StreamReader(fs2))
            {
                contents2 = tr2.ReadToEnd();
                contents1 = tr1.ReadToEnd();
            }
        }
    }
}

Console.WriteLine(contents1);
Console.WriteLine(contents2);

我无法控制锁定文件的进程。 - Malfist

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接