WinRT中的文件共享模式

时间:2016-04-16 23:38:03

标签: logging file-io windows-runtime windows-phone-8.1

我有两个进程编写同一个文件。它是一个日志文件BTW,访问与命名的互斥锁同步。

如何使StorageFolder.OpenStreamForWriteAsync传递FILE_SHARE_READ | FILE_SHARE_WRITE到它可能从kernelbase.dll使用的底层CreateFile2 WinAPI?

1 个答案:

答案 0 :(得分:1)

那是不可能的。

解决方法 - 使用非托管互操作实现您自己的FileStream类。这相对简单,我的代码不到4页。

以下是您需要的导入:

static class NativeMethods
{
    const string file121 = "api-ms-win-core-file-l1-2-1.dll";
    const string handle110 = "api-ms-win-core-handle-l1-1-0.dll";

    [DllImport( file121, CharSet = CharSet.Unicode, SetLastError = true )]
    public static extern SafeFileHandle CreateFile2( [MarshalAs( UnmanagedType.LPWStr )] string filename,
        FileAccess dwDesiredAccess, FileShare dwShareMode, FileMode dwCreationDisposition, IntPtr pCreateExParams );

    [DllImport( handle110, SetLastError = true )]
    [return: MarshalAs( UnmanagedType.Bool )]
    internal static extern bool CloseHandle( IntPtr handle );

    [DllImport( file121, SetLastError = true )]
    [return: MarshalAs( UnmanagedType.Bool )]
    static extern bool GetFileInformationByHandleEx( SafeFileHandle handle, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, out FILE_STANDARD_INFO lpFileInformation, int dwBufferSize );

    internal static FILE_STANDARD_INFO GetFileStandardInfo( SafeFileHandle handle )
    {
        FILE_STANDARD_INFO fsi;
        if( !GetFileInformationByHandleEx( handle, FILE_INFO_BY_HANDLE_CLASS.FileStandardInfo, out fsi, Marshal.SizeOf<FILE_STANDARD_INFO>() ) )
            throw new COMException( "GetFileInformationByHandleEx failed.", Marshal.GetHRForLastWin32Error() );
        return fsi;
    }

    [DllImport( file121, SetLastError = true )]
    [return: MarshalAs( UnmanagedType.Bool )]
    internal static extern bool SetFilePointerEx( SafeFileHandle handle, long liDistanceToMove, out long lpNewFilePointer, SeekOrigin dwMoveMethod );

    [DllImport( file121, SetLastError = true )]
    [return: MarshalAs( UnmanagedType.Bool )]
    internal static extern bool SetFilePointerEx( SafeFileHandle handle, long liDistanceToMove, IntPtr lpNewFilePointer, SeekOrigin dwMoveMethod );

    [DllImport( file121, SetLastError = true )]
    [return: MarshalAs( UnmanagedType.Bool )]
    internal static extern bool FlushFileBuffers( SafeFileHandle handle );

    [DllImport( file121, SetLastError = true )]
    [return: MarshalAs( UnmanagedType.Bool )]
    internal static extern unsafe bool ReadFile( SafeFileHandle hFile, byte* lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped );

    [DllImport( file121, SetLastError = true )]
    [return: MarshalAs( UnmanagedType.Bool )]
    internal static extern unsafe bool SetEndOfFile( SafeFileHandle hFile );

    [ DllImport( file121, SetLastError = true )]
    [return: MarshalAs( UnmanagedType.Bool )]
    internal static extern unsafe bool WriteFile( SafeFileHandle hFile, byte* lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, IntPtr lpOverlapped ); }

您还需要结构/枚举/ SafeFileHandle,但与导入不同,这些很容易复制粘贴,例如来自CoreFX