嗨,我很难让卷影复制服务为我用C++和QT编写的程序工作。快照创建成功,但我无法通过程序或Windows运行提示符访问它(首先不确定这是否可能)。我已尝试使用两者访问快照\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy27\和\Device\WarddiskVolumeShadowCopy 28\作为前缀(根据我的程序生成,末尾有正确的数字)。此外,尽管我使用了VSS_BT_COPY和VSS_BT_FULL作为状态,但快照看起来像是差分快照。我一直在尝试将VSS_CTX_NAS_ROLLBACK作为创建持久快照的上下文,所以在再次尝试访问程序中的快照之前,我尝试将其全部删除,但这次使用的是上下文VSS_CTX_FILE_SHARE_BACKUP,但没有成功。以下是快照创建代码(已删除错误处理):
void Worker::setupVSS(BackupJob &job)
{
HRESULT result;
//backupComponents is a class member variable
//IVssBackupComponents *backupComponents;
result = CreateVssBackupComponents(&backupComponents);
VSS_ID snapshotSetId;
result = backupComponents->InitializeForBackup();
//tried both of these
//result = backupComponents->SetBackupState(FALSE, FALSE, VSS_BT_COPY);
result = backupComponents->SetBackupState(FALSE, FALSE, VSS_BT_FULL);
//tried both of these
//result = backupComponents->SetContext(VSS_CTX_NAS_ROLLBACK);
result = backupComponents->SetContext(VSS_CTX_FILE_SHARE_BACKUP);
result = backupComponents->StartSnapshotSet(&snapshotSetId);
VSS_ID snapshotId;
wchar_t *source;
//this line gets the drive letter with : and
QString driveLetter = job.getSource().mid(0,3);
driveLetter.toWCharArray(source);
//QString("D:\").toWCharArray(source);
result = backupComponents->AddToSnapshotSet(source, GUID_NULL, &snapshotId);
IVssAsync *async;
result = backupComponents->DoSnapshotSet(&async);
result = async->Wait();
async->Release();
VSS_SNAPSHOT_PROP prop;
result = backupComponents->GetSnapshotProperties(snapshotId, &prop);
QString vssPrefix = QString::fromWCharArray(prop.m_pwszSnapshotDeviceObject);
job.setVSSPrefix(vssPrefix);
}
这是打开文件的代码:
QString sourceFileString = job.getCurrentFileSource(fileCount);
if (job.getVSS())
{
QString prefix = job.getVSSPrefix();
//tried this comment to remove ? and globalroot from prefix without success
//prefix = prefix.mid(prefix.indexOf("\Device"));
prefix.append("\");
prefix = QDir::fromNativeSeparators(prefix);
sourceFileString.replace(0,3,prefix);
}
QFile sourceFile(sourceFileString);
if (!sourceFile.open(QIODevice::ReadOnly))
{
updateStatus("<font color="red">ERROR: Couldn't open source file " + QDir::toNativeSeparators(sourceFile.fileName()) + ".</font>");
updateStatus("<font color="red">ERROR: " + sourceFile.errorString() + "</font>");
errorsFound = true;
break;
}
以下是QT从失败的文件打开尝试中给我的错误:
2017年1月13日下午01:42错误:无法打开源文件\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy38\Users\Josh\Desktop\awef\awef3\awefawefawef-复印件(10)
2017年1月13日下午01:42错误:找不到网络路径。
01-13-2017 01:44 PM错误:无法打开源文件\设备\HarddiskVolumeShadowCopy40\Users\Josh\Desktop\awef\awef3\awefawefawef-复印件(10)
2017年1月13日下午01:44错误:系统找不到指定的路径。
当我试图从运行提示打开相同的文件时,它只是说Windows找不到文件名等。
我验证了快照是使用vssadmin列表阴影创建的,输出如下:
卷影复制集ID的内容:{968d9034-3aee-494b-ae78-82af04a15686}在创建时间:1/13/2017下午1:40:09卷影复制ID:{1109bad9-7d01-40f2-9141-cda25b313810}原始卷:(C:)\?\体积{b3fc9fb7-0000-0000-0000-100000000000}\卷影复制卷:\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy38始发机器:joshdesktop10服务机器:joshdesktop10提供程序:'Microsoft软件卷影复制提供程序1.0'类型:FileShareRollback属性:无写入程序,差分
卷影复制集ID的内容:{d6519b09-8325-4c1c-90bc-935a39f2189a}创建时包含1个卷影副本:1/13/2017下午1:44:07卷影复制ID:{21e1b83e-db79-4a29-95b0-65cc5c7d08a8}原始卷:(C:)\?\体积{b3fc9fb7-0000-0000-0000-100000000000}\卷影复制卷:\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy40始发机器:joshdesktop10服务机器:joshdesktop10提供程序:'Microsoft软件卷影复制提供程序1.0'类型:FileShareRollback属性:无写入程序,差分
正如您所看到的,它们是差异备份。。。这会是问题所在吗?
有什么想法吗??谢谢
Google启发了我…因为在这里,如果不使用Win32 API函数FindFirstFile/FindNextFile,您就无法访问VSS快照卷。有一个变通办法。。。将快照卷装载为符号链接,并使用该链接访问文件。这是我使用的代码:
VSS_SNAPSHOT_PROP prop;
result = backupComponents->GetSnapshotProperties(snapshotId, &prop);
wchar_t *snapVol = prop.m_pwszSnapshotDeviceObject;
wcsncat(snapVol, L"\", 1);
if (QDir("C:\repVSSVol").exists())
RemoveDirectory(L"C:\repVSSVol");
if (CreateSymbolicLink(L"C:\repVSSVol", snapVol, SYMBOLIC_LINK_FLAG_DIRECTORY) == 0)
win32Error(TEXT("CreateSymbolicLink"));
还要小心删除符号目录链接,如这里所解释的。