1
我有兩個進程寫入同一個文件。它是一個日誌文件BTW,訪問與一個已命名的互斥體同步。WinRT中的文件共享模式
如何使StorageFolder.OpenStreamForWriteAsync傳遞FILE_SHARE_READ | FILE_SHARE_WRITE到它可能從kernelbase.dll使用的底層CreateFile2 WinAPI?
我有兩個進程寫入同一個文件。它是一個日誌文件BTW,訪問與一個已命名的互斥體同步。WinRT中的文件共享模式
如何使StorageFolder.OpenStreamForWriteAsync傳遞FILE_SHARE_READ | FILE_SHARE_WRITE到它可能從kernelbase.dll使用的底層CreateFile2 WinAPI?
這是不可能的。
解決方法 - 使用非託管互操作實現您自己的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。