English 中文(简体)
避免或取消StgOpenStorage的锁
原标题:Avoid or remove lock from StgOpenStorage()
  • 时间:2009-11-02 15:21:37
  •  标签:

提要

我在的化合物文件,但这一解决办法对我来说是没有工作的。

我试图向StgOpenStorage(StgOpenStorage)开放一个前景。 我的问题是,StgOpenStorage总是锁定我的档案。

因此,我如何避免/取消StgOpenStorage(Sortage)在我的档案中加一门?

(见最后的《开放守则》方法)

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

namespace IStorageLock
{
    [ComImport]
    [Guid("0000000d-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IEnumSTATSTG
    {
        // The user needs to allocate an STATSTG array whose size is celt.
        [PreserveSig]
        uint Next(uint celt,
                  [MarshalAs(UnmanagedType.LPArray), Out]
                  System.Runtime.InteropServices.ComTypes.STATSTG[] rgelt,
                  out uint pceltFetched);

        void Skip(uint celt);
        void Reset();

        [return: MarshalAs(UnmanagedType.Interface)]
        IEnumSTATSTG Clone();
    }

    [ComImport]
    [Guid("0000000b-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IStorage
    {
        void CreateStream(string pwcsName, uint grfMode, uint reserved1,
                          uint reserved2, out IStream ppstm);

        void OpenStream(string pwcsName, IntPtr reserved1, uint grfMode,
                        uint reserved2, out IStream ppstm);

        void CreateStorage(string pwcsName, uint grfMode, uint reserved1,
                           uint reserved2, out IStorage ppstg);

        void OpenStorage(string pwcsName, IStorage pstgPriority, uint grfMode,
                         IntPtr snbExclude, uint reserved, out IStorage ppstg);

        void CopyTo(uint ciidExclude, Guid rgiidExclude, IntPtr snbExclude,
                    IStorage pstgDest);

        void MoveElementTo(string pwcsName, IStorage pstgDest,
                           string pwcsNewName, uint grfFlags);

        void Commit(uint grfCommitFlags);

        void Revert();

        void EnumElements(uint reserved1, IntPtr reserved2, uint reserved3,
                          out IEnumSTATSTG ppenum);

        void DestroyElement(string pwcsName);

        void RenameElement(string pwcsOldName, string pwcsNewName);

        void SetElementTimes(string pwcsName,
                         System.Runtime.InteropServices.ComTypes.FILETIME pctime,
                             System.Runtime.InteropServices.ComTypes.FILETIME patime,
                             System.Runtime.InteropServices.ComTypes.FILETIME pmtime);

        void SetClass(Guid clsid);

        void SetStateBits(uint grfStateBits, uint grfMask);

        void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
                  uint grfStatFlag);
    }

    class Lock
    {
        [Flags]
        public enum STGM : int {
            DIRECT           = 0x00000000,
            TRANSACTED       = 0x00010000,
            SIMPLE           = 0x08000000,
            READ             = 0x00000000,
            WRITE            = 0x00000001,
            READWRITE        = 0x00000002,
            SHARE_DENY_NONE  = 0x00000040,
            SHARE_DENY_READ  = 0x00000030,
            SHARE_DENY_WRITE = 0x00000020,
            SHARE_EXCLUSIVE  = 0x00000010,
            PRIORITY         = 0x00040000,
            DELETEONRELEASE  = 0x04000000,
            NOSCRATCH        = 0x00100000,
            CREATE           = 0x00001000,
            CONVERT          = 0x00020000,
            FAILIFTHERE      = 0x00000000,
            NOSNAPSHOT       = 0x00200000,
            DIRECT_SWMR      = 0x00400000,
        }

        [DllImport("ole32.dll")]
        private static extern int StgIsStorageFile([MarshalAs(UnmanagedType.LPWStr)]
                                                   string pwcsName);

        [DllImport("ole32.dll")]
        static extern int StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)]
                                         string       pwcsName,
                                         IStorage     pstgPriority,
                                         STGM         grfMode,
                                         IntPtr       snbExclude,
                                         uint         reserved,
                                         out IStorage ppstgOpen);

        public IStorage OpenStorage(string fileName)
        {
            if (StgIsStorageFile(fileName) != 0) {
                return null;
            }

            IStorage storage = null;

            //
            // StgOpenStorage() locks file  fileName 
            //
            // Set flags like:
            // [https://stackoverflow.com/questions/1086814/opening-ole-compound-documents-read-only-with-stgopenstorage]
            //
            int stgOpenStorage = StgOpenStorage(fileName, null,
                                                STGM.READ            |
                                                STGM.SHARE_DENY_NONE |
                                                STGM.TRANSACTED,
                                                IntPtr.Zero, 0,
                                                out storage);

            //
            // Try to rename file (for testing purposes only)
            //
            try {
                File.Move(fileName, fileName + @".renamed");
            } catch (Exception ex) {        // exception: file alreay in use by another process
                throw;
            }

            if (stgOpenStorage != 0) {
                return null;
            } else {
                return storage;
            }
        }
    }
}

希望能帮助我。

关于

页: 1

问题回答

你们是否试图用StgOpenStorageOnILockBytes来读档案?





相关问题
热门标签