Использование SafeFileHandle в приложении UWP - PullRequest
0 голосов
/ 09 ноября 2018

Я пишу приложение 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)

1 Ответ

0 голосов
/ 09 ноября 2018

Я еще немного покопался и использовал ваш пример, чтобы воспроизвести проблему.Я считаю, что проблема в том, что вы не можете использовать CreateSafeFileHandle в своем приложении UWP, оно помечено как 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)

...