- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是一个令人难以置信的远射,但这里是。我们正在使用 SQLVDI API(虚拟设备接口(interface))制作数据库备份实用程序。单一备份的实现没有问题。但是当我们开始实现 strip 备份(使用 virtual_device)时,我们遇到了 IClientVirtualDeviceSet2::OpenDevice
方法的问题。我们的虚拟设备集无法打开所有设备。仅返回第一个设备,在第二个设备上我们收到 VD_E_PROTOCOL
错误。任何建议将不胜感激。
我们的 C++ 代码。
public: Void ExecuteCommandEx(System::String^ command, array<Stream^>^ commandStreamListIn)
{
try
{
//Initialize COM
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr))
{
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "CoInitializeEx Failed HRESULT: {0}", hr));
}
//Get an interface to the virtual device set
IClientVirtualDeviceSet2* vds = NULL;
hr = CoCreateInstance(CLSID_MSSQL_ClientVirtualDeviceSet, NULL, CLSCTX_INPROC_SERVER, IID_IClientVirtualDeviceSet2, (void**)&vds);
if (FAILED(hr))
{
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "Unable to get an interface to the virtual device set. Please check to make sure sqlvdi.dll is registered. HRESULT: {0}", hr));
}
//Configure the device configuration
VDConfig config = { 0 };
config.deviceCount = commandStreamListIn->Length; //The number of virtual devices to create
//Create a name for the device using a GUID
String^ DeviceName = Guid::NewGuid().ToString()->ToUpper(gcnew CultureInfo("en-US"));
WCHAR wVdsName[37] = { 0 };
Marshal::Copy(DeviceName->ToCharArray(), 0, (IntPtr)wVdsName, DeviceName->Length);
//Create the virtual device set
hr = vds->CreateEx(NULL, wVdsName, &config);
if (FAILED(hr))
{
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "Unable to create and configure the virtual device set. HRESULT: {0}", hr));
}
//Format the command
List<String^>^ vdNames = gcnew List<String^>();
vdNames->Add(DeviceName);
for (int i = 0; i < commandStreamListIn->Length-1; i++)
{
String^ streamName = Guid::NewGuid().ToString()->ToUpper(gcnew CultureInfo("en-US"));
vdNames->Add(streamName);
}
command = String::Format(gcnew CultureInfo("en-US"), command, vdNames->ToArray());
//Create and execute a new thread to execute the command
Thread^ OdbcThread = gcnew Thread(gcnew ParameterizedThreadStart(this, &VdiDotNetEx::VdiEngineEx::ThreadFunc));
OdbcThread->Start(command);
//Configure the virtual device set
hr = vds->GetConfiguration(INFINITE, &config);
if (hr != NOERROR)
{
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "GetConfiguration Failed. HRESULT: {0}", hr));
}
if (FAILED(hr))
{
switch (hr)
{
case VD_E_ABORT:
throw gcnew ApplicationException("GetConfiguration was aborted.");
break;
case VD_E_TIMEOUT:
throw gcnew ApplicationException("GetConfiguration timed out.");
break;
default:
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "Un unknown exception was thrown during GetConfiguration. HRESULT: {0}", hr));
break;
};
}
int count = 0;
array<IClientVirtualDevice*>^ vDevices= gcnew array<IClientVirtualDevice*>(commandStreamListIn->Length);
//Open all devices on the device set
//VD_E_OPEN may be returned without problem. The client may call OpenDevice by means of a loop until this code is returned.
//If more than one device is configured(for example, n devices),
//the virtual device set will return n unique device interfaces.
//The first device has the same name as the virtual device set.
//Other devices are named as specified with the VIRTUAL_DEVICE clauses of the BACKUP / RESTORE statement.
while (hr!= VD_E_OPEN)
{
IClientVirtualDevice* vd = NULL;
hr = vds->OpenDevice(wVdsName, &vd);
switch(hr)
{
case VD_E_OPEN:
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_OPEN. HRESULT: {0}", hr));
break;
case VD_E_BUSY:
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_BUSY. HRESULT: {0}", hr));
break;
case VD_E_CLOSE:
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_CLOSE. HRESULT: {0}", hr));
break;
case VD_E_UNEXPECTED:
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_UNEXPECTED. HRESULT: {0}", hr));
break;
case VD_E_INVALID:
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_INVALID. HRESULT: {0}", hr));
break;
case VD_E_NOTOPEN:
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_NOTOPEN. HRESULT: {0}", hr));
break;
case VD_E_PROTOCOL:
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_PROTOCOL. HRESULT: {0}", hr));
break;
}
if (FAILED(hr))
{
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. HRESULT: {0}", hr));
}
vDevices[count] = vd;
count++;
}
for (int i = 0; i < count; i++)
{
ExecuteDataTransfer(vDevices[i], commandStreamListIn[i]);
}
//Wait for the thread that issued the backup / restore command to SQL Server to complete.
OdbcThread->Join();
}
catch (Exception ^ex)
{
Debug::WriteLine("VDI: Exception=" + ex->Message->ToString());
Debug::WriteLine("VDI: Trace=" + ex->StackTrace);
Console::WriteLine(ex->Message);
LogException(ex);
throw gcnew ApplicationException(ex->Message);
}
}
COM相关代码:(combaseapi.h)
#pragma region Application or OneCore Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
_Check_return_ WINOLEAPI
CoInitializeEx(
_In_opt_ LPVOID pvReserved,
_In_ DWORD dwCoInit
);
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
#pragma endregion
_Check_return_ WINOLEAPI
CoCreateInstance(
_In_ REFCLSID rclsid,
_In_opt_ LPUNKNOWN pUnkOuter,
_In_ DWORD dwClsContext,
_In_ REFIID riid,
_COM_Outptr_ _At_(*ppv, _Post_readable_size_(_Inexpressible_(varies))) LPVOID FAR * ppv
);
最佳答案
根据 SQLVDI 文档,OpenDevice 不工作。例如,不要期望 VD_E_OPEN 作为结果,只需 0 即可。此外,不仅要将虚拟设备集名称传递给此方法,还要传递命令中每个 virtual_device 的 GUID。看看这个调整后的代码。
for(int i = 0; i < vdNames->Count; i++)
{
IClientVirtualDevice* vd = NULL;
WCHAR wDevName[37] = { 0 };
String^ vdName = vdNames[i];
Marshal::Copy(vdName->ToCharArray(), 0, (IntPtr)wDevName, vdName->Length);
hr = vds->OpenDevice(wDevName, &vd);
switch(hr)
{
case VD_E_BUSY:
DBGPRINTW(L"VDI: Exception 15\n");
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_BUSY. HRESULT: {0}", hr));
break;
case VD_E_CLOSE:
DBGPRINTW(L"VDI: Exception 14\n");
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_CLOSE. HRESULT: {0}", hr));
break;
case VD_E_UNEXPECTED:
DBGPRINTW(L"VDI: Exception 11\n");
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_UNEXPECTED. HRESULT: {0}", hr));
break;
case VD_E_INVALID:
DBGPRINTW(L"VDI: Exception 06\n");
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_INVALID. HRESULT: {0}", hr));
break;
case VD_E_NOTOPEN:
DBGPRINTW(L"VDI: Exception 02\n");
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_NOTOPEN. HRESULT: {0}", hr));
break;
case VD_E_PROTOCOL:
DBGPRINTW(L"VDI: Exception 12\n");
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. VD_E_PROTOCOL. HRESULT: {0}", hr));
break;
}
if (FAILED(hr))
{
DBGPRINTW(L"VDI: Exception 08\n");
throw gcnew ApplicationException(String::Format(gcnew CultureInfo("en-US"), "OpenDevice Failed. HRESULT: {0}", hr));
}
vDevices[i] = vd;
count++;
}
关于c++ - 无法使用 SQL VDI(虚拟设备接口(interface))创建 strip 化备份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59156030/
前言: 有时候,一个数据库有多个帐号,包括数据库管理员,开发人员,运维支撑人员等,可能有很多帐号都有比较大的权限,例如DDL操作权限(创建,修改,删除存储过程,创建,修改,删除表等),账户多了,管理
所以我用 Create React App 创建并设置了一个大型 React 应用程序。最近我们开始使用 Storybook 来处理和创建组件。它很棒。但是,当我们尝试运行或构建应用程序时,我们不断遇
遵循我正在创建的控件的代码片段。这个控件用在不同的地方,变量也不同。 我正在尝试编写指令来清理代码,但在 {{}} 附近插入值时出现解析错误。 刚接触 Angular ,无法确定我错过了什么。请帮忙。
我正在尝试创建一个 image/jpeg jax-rs 提供程序类,它为我的基于 post rest 的 Web 服务创建一个图像。我无法制定请求来测试以下内容,最简单的测试方法是什么? @POST
我一直在 Windows 10 的模拟器中练习 c。后来我改用dev C++ IDE。当我在 C 中使用 FILE 时。创建的文件的名称为 test.txt ,而我给出了其他名称。请帮助解决它。 下面
当我们创建自定义 View 时,我们将 View 文件的所有者设置为自定义类,并使用 initWithFrame 或 initWithCode 对其进行实例化。 当我们创建 customUITable
我正在尝试为函数 * Producer 创建一个线程,但用于创建线程的行显示错误。我为这句话加了星标,但我无法弄清楚它出了什么问题...... #include #include #include
今天在做项目时,遇到了需要创建JavaScript对象的情况。所以Bing了一篇老外写的关于3种创建JavaScript对象的文章,看后跟着打了一遍代码。感觉方法挺好的,在这里与大家分享一下。 &
我正在阅读将查询字符串传递给 Amazon 的 S3 以进行身份验证的文档,但似乎无法理解 StringToSign 的创建和使用方式。我正在寻找一个具体示例来说明 (1) 如何构造 String
前言:我对 C# 中任务的底层实现不太了解,只了解它们的用法。为我在下面屠宰的任何东西道歉: 对于“我怎样才能开始一项任务但不等待它?”这个问题,我找不到一个好的答案。在 C# 中。更具体地说,即使任
我有一个由一些复杂的表达式生成的 ILookup。假设这是按姓氏查找人。 (在我们简单的世界模型中,姓氏在家庭中是唯一的) ILookup families; 现在我有两个对如何构建感兴趣的查询。 首
我试图创建一个 MSI,其中包含 和 exe。在 WIX 中使用了捆绑选项。这样做时出错。有人可以帮我解决这个问题。下面是代码: 错误 error LGH
在 Yii 中,Create 和 Update 通常使用相同的形式。因此,如果我在创建期间有电子邮件、密码、...other_fields...等字段,但我不想在更新期间专门显示电子邮件和密码字段,但
上周我一直在努力创建一个给定一行和一列的 QModelIndex。 或者,我会满足于在已经存在的 QModelIndex 中更改 row() 的值。 任何帮助,将不胜感激。 编辑: QModelInd
出于某种原因,这不起作用: const char * str_reset_command = "\r\nReset"; const char * str_config_command = "\r\nC
现在,我有以下由 original.df %.% group_by(Category) %.% tally() %.% arrange(desc(n)) 创建的 data.frame。 DF 5),
在今天之前,我使用/etc/vim/vimrc来配置我的vim设置。今天,我想到了创建.vimrc文件。所以,我用 touch .vimrc cat /etc/vim/vimrc > .vimrc 所
我可以创建一个 MKAnnotation,还是只读的?我有坐标,但我发现使用 setCooperative 手动创建 MKAnnotation 并不容易。 想法? 最佳答案 MKAnnotation
在以下代码中,第一个日志语句按预期显示小数,但第二个日志语句记录 NULL。我做错了什么? NSDictionary *entry = [[NSDictionary alloc] initWithOb
我正在使用与此类似的代码动态添加到数组; $arrayF[$f+1][$y][$x+1] = $value+1; 但是我在错误报告中收到了这个: undefined offset :1 问题:尝试创
我是一名优秀的程序员,十分优秀!