![](/img/trans.png)
[英]Windows 10 Creators update .net 4.7 System.AccessViolationException issue
[英]System.AccessViolationException when copying data to portable device after installing windows 10 creators update 1703
我正在尝试使用此代码段将内容传输到便携式设备
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。
你能告诉我我做错了什么吗?
提前致谢。
- 如果您只想修复,请跳转到粗体文本!
进一步调查,问题在于低级本机API:ISequentialStream :: Write(IStream Inherits)MSDN页面为: https : //msdn.microsoft.com/en-us/library/windows/desktop/aa380014 %28V = vs.85%29.aspx?F = 255&MSPPError = -2147217396
请注意参数的文本:pcbWritten [out]读取'指向ULONG变量的指针,其中此方法写入写入流对象的实际字节数。 调用者可以将此指针设置为NULL,在这种情况下,此方法不会提供实际写入的字节数。
MS在此API中引入了一个错误(在PortableDeviceApi.dll中调用) - >在尝试从此变量读取/写入之前,它不再检查pcbWritten是否为NULL - 相反,它总是尝试写入No Of Bytes写入此变量 - 如果使用此变量设置为NULL调用API,则将其设置为BARFS。 我已经通过改变调用API的方式证明了纯本机代码的情况:
作品:
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循环中的多块副本,我怀疑alloc / free可以在没有问题的情况下在外面完成。 如果MS确实修复了bug,也应该是安全的。
信用:Alistair Brown(在我们的办公室)钓鱼,并分配不需要分配的东西,从而找到问题。
奈杰尔
经过几天的讨论,在另一个线程上调用它解决了这个问题:
var t = Task.Run(() => { device.TransferContentToDevice(fileName, parent.Id); });
t.Wait();
我也有同样的问题,它看起来是Windows 10的Creators Edition build 1703中的一个bug /功能。
已通过Microsoft Connect上的“Visual Studio和.Net Framework”流报告此问题: https : //connect.microsoft.com/VisualStudio/Feedback/Details/3135829 (Windows 10没有特定区域)
我会鼓励任何有这个问题的人前往上面,并表明你也可以重现它。
我有一个简单的中继器,可以在这里下载: http : //scratch.veletron.com/WPD_FAIL_REPEATER.ZIP
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.