Привет, у меня проблемы с получением службы теневого копирования томов для моей программы, написанной на C ++ с QT. Снимок создан успешно, однако я не могу получить к нему доступ ни через свою программу, ни через приглашение Windows (не уверен, если это вообще возможно). Я попытался получить доступ к снимку, используя оба префикса \\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy27 \ и \ Device \ HarddiskVolumeShadowCopy28 \ (сгенерированные из моей программы с нужным номером в конце). Также снимки выглядят так, как будто они являются дифференциальными снимками, хотя я использовал 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 из-за неудачной попытки открытия файла:
13.01.2017 13:42 ОШИБКА: Не удалось открыть исходный файл
\\? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy38 \ Users \ Josh \ Desktop \ awef \ awef3 \ awefawefawef
— Копировать (10) waefawefawefawefawefawef — Copyawefawefawefawefawefwefawefawef.docx.01-13-2017 13:42 ОШИБКА:
Сетевой путь не найден.13.01.2017 13:44 ОШИБКА: Не удалось открыть исходный файл
\ Device \ HarddiskVolumeShadowCopy40 \ Users \ Josh \ Desktop \ awef \ awef3 \ awefawefawef
— Копировать (10) waefawefawefawefawefawef — Copyawefawefawefawefawefwefawefawef.docx.01-13-2017 13:44 ОШИБКА:
Система не может найти указанный путь.
Когда я пытаюсь открыть те же файлы из командной строки, он просто говорит, что Windows не может найти имя файла так далее..
Я проверил, что моментальные снимки создаются с использованием теней списка vssadmin с таким выводом:
Содержимое идентификатора набора теневой копии:
{968d9034-3aee-494b-ae78-82af04a15686} Содержит 1 теневую копию на
время создания: 13.01.2017 13:40:09
Идентификатор теневой копии: {1109bad9-7d01-40f2-9141-cda25b313810}
Исходный том: (C:) \? \ Volume {b3fc9fb7-0000-0000-0000-100000000000} \
Том теневого копирования: \? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy38
Происходящая машина: joshdesktop10
Сервисная машина: joshdesktop10
Поставщик: «Поставщик ПО Microsoft Shadow Copy 1.0»
Тип: FileShareRollback
Атрибуты: нет авторов, дифференциалСодержимое идентификатора набора теневых копий: {d6519b09-8325-4c1c-90bc-935a39f2189a}
Содержится 1 теневая копия во время создания: 13.01.2017 13:44:07
Идентификатор теневой копии: {21e1b83e-db79-4a29-95b0-65cc5c7d08a8}
Исходный том: (C:) \? \ Volume {b3fc9fb7-0000-0000-0000-100000000000} \
Том теневого копирования: \? \ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy40
Инициирующая машина: joshdesktop10
Сервисная машина: joshdesktop10
Поставщик: «Поставщик ПО Microsoft Shadow Copy 1.0»
Тип: FileShareRollback
Атрибуты: нет авторов, дифференциал
Как вы можете видеть, они являются дифференциальными резервными копиями … может ли это быть проблемой?
Есть идеи?? Спасибо!
Google просветил меня … как Вот Вы не можете получить доступ к томам моментальных снимков VSS без использования функций Win32 API FindFirstFile / FindNextFile. Существует обходной путь … смонтируйте том снимка как символическую ссылку и используйте ссылку для доступа к файлам. Вот код, который я использовал:
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"));
Также будьте осторожны, удаляя символические ссылки на каталоги, как описано Вот.
Других решений пока нет …