2016-04-16 8 views
1

Ich habe zwei Prozesse, die die gleiche Datei schreiben. Es ist eine Protokolldatei BTW, der Zugriff wird mit einem benannten Mutex synchronisiert.Dateifreigabe-Modus in WinRT

Wie mache ich StorageFolder.OpenStreamForWriteAsync übergeben FILE_SHARE_READ | FILE_SHARE_WRITE zum zugrunde liegenden CreateFile2 WinAPI, das es wahrscheinlich von kernelbase.dll verwendet?

Antwort

1

Das ist unmöglich.

Die Problemumgehung - implementieren Sie Ihre eigene FileStream-Klasse mit nicht verwalteten Interop. Das ist relativ einfach, meins ist unter 4 Seiten Code.

Hier ist der Import Sie dafür brauchen:

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); } 

Sie müssen auch Strukturen/Aufzählungen/Safefilehandle, aber im Gegensatz zu Importen, die sind einfach zu kopieren-Paste, z.B. von CoreFX.