在 UWP 应用程序中使用 SafeFileHandle
Posted
技术标签:
【中文标题】在 UWP 应用程序中使用 SafeFileHandle【英文标题】:Using SafeFileHandle in UWP application 【发布时间】:2019-04-13 04:11:37 【问题描述】:我正在编写一个 UWP 应用程序,我正在使用 StorageFile
类将配置文件保存到硬盘,但偶尔文件没有更新(主要是在您按下保存按钮后退出应用程序时)。
我尝试了以下代码,它在调试模式下按预期工作,但是当我尝试在发布模式下编译时,出现以下错误:
C:\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\microsoft.net.native.compiler\2.1.8\tools\Microsoft.NetNative.targets(788,5): error : ILT0014: Failed to compile interop source code. See the build log for error details.
var msg = new Windows.UI.Popups.MessageDialog("Configuration file updated successfully");
var handle = file.CreateSafeFileHandle(options: FileOptions.WriteThrough);
if (handle != null)
using (FileStream stream = new FileStream(handle, FileAccess.ReadWrite))
byte[] data = new UTF8Encoding(true).GetBytes(set);
stream.Write(data, 0, data.Length);
stream.Flush(true);
await msg.ShowAsync();
else
await Windows.Storage.FileIO.WriteTextAsync(file, set);
await msg.ShowAsync();
我使用以下代码创建了一个新的 UWP 应用程序,并且收到相同的错误消息:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace SampleApp
public sealed partial class MainPage : Page
public MainPage()
this.InitializeComponent();
WriteFile();
public async void WriteFile()
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
var file = await localFolder.CreateFileAsync("TestFile.txt", CreationCollisionOption.ReplaceExisting);
var handle = file.CreateSafeFileHandle(options: FileOptions.WriteThrough);
string text = "This is a test string";
if (handle != null)
using (FileStream stream = new FileStream(handle, FileAccess.ReadWrite))
byte[] data = new UTF8Encoding(true).GetBytes("This is a test string");
stream.Write(data, 0, data.Length);
stream.Flush(true);
else
await Windows.Storage.FileIO.WriteTextAsync(file, text);
构建错误:
1> Imported reflection directives from 7 files: (TaskId:323)
1> C:\Users\MHosseini\Documents\Visual Studio 2017\Projects\SampleApp\obj\x86\Release\ilc\in\Properties\Default.rd.xml (TaskId:323)
1> Embedded manifest in System.Private.Interop: Resources.System.Private.Interop.rd.xml (TaskId:323)
1> Embedded manifest in System.Private.WinRTInterop.CoreLib: Resources.System.Private.WinRTInterop.CoreLib.rd.xml (TaskId:323)
1> Embedded manifest in System.Runtime.WindowsRuntime.UI.Xaml: Resources.System.Runtime.WindowsRuntime.UI.Xaml.rd.xml (TaskId:323)
1> Embedded manifest in System.Private.CoreLib: Resources.System.Private.CoreLib.rd.xml (TaskId:323)
1> Embedded manifest in System.Private.Uri: Resources.System.Private.Uri.rd.xml (TaskId:323)
1> Embedded manifest in System.Private.Reflection.Core: System.Private.Reflection.Core.rd.xml (TaskId:323)
1> Imported XAML Roots from 1 files: (TaskId:323)
1> C:\Users\MHosseini\Documents\Visual Studio 2017\Projects\SampleApp\obj\x86\Release\ilc\in\SampleApp.xr.xml (TaskId:323)
1> Running 'Mcg' transform, heap at 210 MB. (TaskId:323)
1> Computing application closure and generating interop code (TaskId:323)
1> Loading 46 modules... (TaskId:323)
1> P/Invoke 'RhpGetFuncEvalParameterBufferSize' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!RhpGetFuncEvalParameterBufferSize'. (TaskId:323)
1> P/Invoke 'RhpGetFuncEvalMode' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!RhpGetFuncEvalMode'. (TaskId:323)
1> P/Invoke 'RhpRecordDebuggeeInitiatedHandle' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!RhpRecordDebuggeeInitiatedHandle'. (TaskId:323)
1> P/Invoke 'RhpVerifyDebuggerCleanup' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!RhpVerifyDebuggerCleanup'. (TaskId:323)
1> P/Invoke 'RhpGetCurrentThread' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!RhpGetCurrentThread'. (TaskId:323)
1> P/Invoke 'RhWaitForPendingFinalizers' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!RhWaitForPendingFinalizers'. (TaskId:323)
1> P/Invoke 'RhYield' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!RhYield'. (TaskId:323)
1> P/Invoke 'RhFlushProcessWriteBuffers' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!RhFlushProcessWriteBuffers'. (TaskId:323)
1> P/Invoke 'RhCompatibleReentrantWaitAny' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!RhCompatibleReentrantWaitAny'. (TaskId:323)
1> P/Invoke 'RhCallDescrWorker' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!RhCallDescrWorker'. (TaskId:323)
1> P/Invoke '_ecvt_s' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!_ecvt_s'. (TaskId:323)
1> P/Invoke 'memmove' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!memmove'. (TaskId:323)
1> P/Invoke 'memset' with [DllImport(ExactSpelling=true)] resolved to '[MRT]!memset'. (TaskId:323)
1> P/Invoke 'CallingConventionConverter_GetStubs' with [DllImport(ExactSpelling=true)] resolved to '*!CallingConventionConverter_GetStubs'. (TaskId:323)
1> P/Invoke 'WindowsCreateStringReference' resolved to 'WindowsCreateStringReference!api-ms-win-core-winrt-string-l1-1-0.dll' from 'SupportedAPIs.xml'. (TaskId:323)
1> P/Invoke 'GetLastError' resolved to 'GetLastError!api-ms-win-core-errorhandling-l1-1-0.dll' from 'SupportedAPIs.xml'. (TaskId:323)
1> P/Invoke 'SetLastError' resolved to 'SetLastError!api-ms-win-core-errorhandling-l1-1-0.dll' from 'SupportedAPIs.xml'. (TaskId:323)
1> P/Invoke 'RoInitialize' resolved to 'RoInitialize!api-ms-win-core-winrt-l1-1-0.dll' from 'SupportedAPIs.xml'. (TaskId:323)
1> P/Invoke 'IsValidLocaleName' resolved to 'IsValidLocaleName!api-ms-win-core-localization-l1-2-0.dll' from 'SupportedAPIs.xml'. (TaskId:323)
1> P/Invoke 'ResolveLocaleName' resolved to 'ResolveLocaleName!api-ms-win-core-localization-l1-2-0.dll' from 'SupportedAPIs.xml'. (TaskId:323)
1> P/Invoke 'GetCPInfoExW' resolved to 'GetCPInfoExW!kernel32.dll' from 'SupportedAPIs.xml'. (TaskId:323)
1> P/Invoke 'CoCreateInstance' with [DllImport(ExactSpelling=true)] resolved to 'api-ms-win-core-com-l1-1-0.dll!CoCreateInstance'. (TaskId:323)
1> P/Invoke 'FormatMessageW' resolved to 'FormatMessageW!kernel32.dll' from 'SupportedAPIs.xml'. (TaskId:323)
1> P/Invoke 'SysFreeString' resolved to 'SysFreeString!OleAut32' from 'SupportedAPIs.xml'. (TaskId:323)
1> P/Invoke 'RoGetBufferMarshaler' resolved to 'RoGetBufferMarshaler!api-ms-win-core-winrt-robuffer-l1-1-0.dll' from 'SupportedAPIs.xml'. (TaskId:323)
1> Generating code... (TaskId:323)
1> Interop code generated. (TaskId:323)
1> Written code to AssemblyInfo.g.cs (TaskId:323)
1> Written code to Adapters.g.cs (TaskId:323)
1> Written code to Data.g.cs (TaskId:323)
1> Written code to Helpers.g.cs (TaskId:323)
1> Written code to ImplTypes.g.cs (TaskId:323)
1> Written code to PInvoke.g.cs (TaskId:323)
1> Written code to SafeTypes.g.cs (TaskId:323)
1> Written code to SharedStubs.g.cs (TaskId:323)
1> Running 'GenerateCodeAndCompile' transform, heap at 173 MB. (TaskId:323)
1> Compiling interop code (TaskId:323)
1> Compiling generated source code: C:\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\microsoft.net.native.compiler\2.1.8\tools\csc\csc.exe /noconfig @"C:\Users\MHosseini\Documents\Visual Studio 2017\Projects\SampleApp\obj\x86\Release\ilc\intermediate\SampleApp.McgInterop.rsp" (TaskId:323)
1> obj\x86\Release\ilc\intermediate\SampleApp.McgInterop\ImplTypes.g.cs(5577,11): error CS1620: Argument 5 must be passed with the 'out' keyword (TaskId:323)
1>C:\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\microsoft.net.native.compiler\2.1.8\tools\Microsoft.NetNative.targets(788,5): error : ILT0014: Failed to compile interop source code. See the build log for error details.
1> Done executing task "RunILTransforms" -- FAILED. (TaskId:323)
1> Done building target "RunILTransforms" in file "ILTransforms" -- FAILED. (TaskId:323)
1> Done building project "ILTransforms" -- FAILED. (TaskId:323)
1> Compilation failed (TaskId:323)
1> (TaskId:323)
1> The command exited with code 1201. (TaskId:323)
1> Output Property: _IlcExitCode=1201 (TaskId:323)
1>Done executing task "LoggerBasedExecTask" -- FAILED. (TaskId:323)
1>Done building target "BuildNativePackage" in project "SampleApp.csproj" -- FAILED.: (TargetId:142)
1>Target "LogIlcBehavioralDifference: (TargetId:143)" in file "C:\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\microsoft.net.native.compiler\2.1.8\tools\Microsoft.NetNative.targets" from project "C:\Users\MHosseini\Documents\Visual Studio 2017\Projects\SampleApp\SampleApp.csproj" (target "BuildNativePackage" depends on it):
1>Set Property: _IlcMinBehavioralExitCode=1400
1>Task "IlcErrorTask" skipped, due to false condition; ('$(_IlcExitCode)' != '' and '$(_IlcExitCode)' >= '$(_IlcMinBehavioralExitCode)') was evaluated as ('1201' != '' and '1201' >= '1400').
1>Done building target "LogIlcBehavioralDifference" in project "SampleApp.csproj".: (TargetId:143)
1>Target "_CheckForCompileOutputs" skipped. Previously built successfully.
1>Target "_SGenCheckForOutputs" skipped, due to false condition; ('$(_SGenGenerateSerializationAssembliesConfig)' == 'On' or ('@(WebReferenceUrl)'!='' and '$(_SGenGenerateSerializationAssembliesConfig)' == 'Auto')) was evaluated as ('Auto' == 'On' or (''!='' and 'Auto' == 'Auto')).
1>Target "_CleanGetCurrentAndPriorFileWrites: (TargetId:144)" in file "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets" from project "C:\Users\MHosseini\Documents\Visual Studio 2017\Projects\SampleApp\SampleApp.csproj" (target "_CleanRecordFileWrites" depends on it):
1>Using "ReadLinesFromFile" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
1>Task "ReadLinesFromFile" (TaskId:324)
1> Task Parameter:File=obj\x86\Release\SampleApp.csproj.FileListAbsolute.txt (TaskId:324)
1>Done executing task "ReadLinesFromFile". (TaskId:324)
【问题讨论】:
构建日志错误详细信息为您提供了哪些信息?你有任何编译器警告吗? @pstrjds 我已经用构建日志更新了我的问题 你提供的文件链接是源代码文件,不是构建日志,但是如果你只是粘贴构建日志的相关部分,错误发生的地方等会更好。跨度> 为什么需要 SafeFileHandle 来创建 FileStream?为此有 OpenStreamForReadAsync 或 OpenReadAsync/AsStreamForRead API。 @zabulus 我想写入文件,我不想设置FileOptions.WriteThrough
选项
【参考方案1】:
我进行了更多挖掘并使用您的示例重现了该问题。我相信我们无法在 UWP 应用程序中使用CreateSafeFileHandle
的问题,它被标记为Windows 10 [Desktop Only]
。请参阅此处的文档:https://docs.microsoft.com/en-us/windows/desktop/api/windowsstoragecom/nf-windowsstoragecom-istorageitemhandleaccess-create
您可以在有关 UWP 应用程序未在发布模式下编译的帖子中查看此答案 - https://developercommunity.visualstudio.com/solutions/306477/view.html
这与您看到的错误相同:
SampleApp.McgInterop\ImplTypes.g.cs(5577,11):错误 CS1620:参数 5 必须与“out”关键字一起传递 (TaskId:323)
【讨论】:
以上是关于在 UWP 应用程序中使用 SafeFileHandle的主要内容,如果未能解决你的问题,请参考以下文章