gpt4 book ai didi

c# - 安装 windows 10 creators update 1703 后将数据复制到可移植设备时出现 System.AccessViolationException

转载 作者:太空狗 更新时间:2023-10-29 23:05:25 25 4
gpt4 key购买 nike

我正在尝试使用此代码片段将内容传输到可移植设备

IPortableDeviceValues values =
GetRequiredPropertiesForContentType(fileName, parentObjectId);

IStream tempStream;
uint optimalTransferSizeBytes = 0;

content.CreateObjectWithPropertiesAndData(
values,
out tempStream,
ref optimalTransferSizeBytes,
null);

System.Runtime.InteropServices.ComTypes.IStream targetStream =
(System.Runtime.InteropServices.ComTypes.IStream)tempStream;

try
{
using (var sourceStream =
new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[optimalTransferSizeBytes];
int bytesRead;
do
{
bytesRead = sourceStream.Read(
buffer, 0, (int)optimalTransferSizeBytes);
IntPtr pcbWritten = IntPtr.Zero;
if (bytesRead < (int)optimalTransferSizeBytes)
{
targetStream.Write(buffer, bytesRead, pcbWritten);
}
else
{
targetStream.Write(buffer, (int)optimalTransferSizeBytes, pcbWritten);
}

} while (bytesRead > 0);
}
targetStream.Commit(0);
}
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(tempStream);
}

尝试执行 targetStream.Write 时发生 System.AccessViolationException。

这仅适用于 Windows 10,创作者更新 1703。

你能告诉我我做错了什么吗?

提前致谢。

最佳答案

--如果您只想修复,请跳至粗体文本!

进一步调查,问题出在低级 native API 中:ISequentialStream::Write(IStream 继承)MSDN 页面为:https://msdn.microsoft.com/en-us/library/windows/desktop/aa380014%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

注意参数的文本:pcbWritten [out] reads'指向 ULONG 变量的指针,此方法在其中写入写入流对象的实际字节数。调用者可以将此指针设置为 NULL,在这种情况下,此方法不提供实际写入的字节数。'

MS 在此 API 中引入了一个错误(在 PortableDeviceApi.dll 中调用)--> 在尝试从此变量读取/写入之前,它不再检查 pcbWritten 是否为 NULL - 相反,它总是尝试写入没有写入此变量的字节 - 如果调用 API 时将此变量设置为 NULL,则它会 BARFS。我已经通过更改调用 API 的方式在纯 native 代码中证明了这种情况:

作品:

DWORD bytesWritten
IStream->Write(objectData, bytesRead, &bytesWritten)))

失败:

IStream->Write(objectData, bytesRead, NULL))) <-- Note the NULL

在 .Net 中,IStream.Write 是这样编码的:

void Write(byte[] pv,int cb,IntPtr pcbWritten)

演示代码(我们都可能从中获得实现!)是:

 IntPtr pcbWritten = IntPtr.Zero  //<--Eg NULL
IStream.Write(buffer, bytesRead, pcbWritten);

建议的解决方案 - 将代码更改为:

 IntPtr pcbWritten = Marshal.AllocHGlobal(4);
IStream.Write(buffer, bytesRead, pcbWritten);
Marshal.FreeHGlobal(pcbWritten);

这解决了这个问题 - 希望 MS 能够修复它以避免我们所有人都不得不重新分发我们的产品!整个代码包含在 PortableDeviceApi.dll 中(也包括流的东西),这可以解释为什么整个世界都没有提示这个问题以及为什么在测试期间没有发现它。注意:对于 while 循环中的多 block 副本,我怀疑 alloc/free 可以在 while 之外完成而不会出现问题。如果 MS 确实修复了该错误,也应该是安全的。

致谢:Alistair Brown(在我们办公室)四处摸索,分配不需要分配的内容,从而找到问题。

奈杰尔

关于c# - 安装 windows 10 creators update 1703 后将数据复制到可移植设备时出现 System.AccessViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43980646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com