コード例 #1
1
        /// <summary>
        /// Loads a <see cref="PropertyStore"/> for the specified file or extension, containing only the specified properties. Note that if creating a PropertyStore based on extension only, this store will be read only. The <see cref="GetFlags.BestEffort"/>
        /// should be used for retrieving that store, as the file does not exist to enable the reading of properties that would be stored in it, and any other flags are likely to produce an exception.
        /// </summary>
        /// <param name="path">The path or extension of the file the store is required for</param>
        /// <param name="keys">The required <see cref="PropertyKey"/>s</param>
        /// <param name="flags">The <see cref="GetFlags"/> indicating the type of store to load</param>
        public PropertyStore(string path, IEnumerable <PropertyKey> keys, GetFlags flags)
        {
            int    nKeys    = keys.Count();
            IntPtr keyArray = Marshal.AllocCoTaskMem(nKeys * Marshal.SizeOf(typeof(PROPERTYKEY)));

            try {
                IntPtr keyPtr = keyArray;
                foreach (PropertyKey key in keys)
                {
                    Marshal.StructureToPtr <PROPERTYKEY>(key.PROPERTKEY, keyPtr, false);
                    keyPtr += Marshal.SizeOf(typeof(PROPERTYKEY));
                }
                if (File.Exists(path))
                {
                    IntPtr pidl = ILCreateFromPath(Path.GetFullPath(path));
                    try {
                        IntPtr shUnk = IntPtr.Zero;
                        SHCreateItemFromIDList(pidl, IID.IShellItem2, out shUnk);
                        _pSource = (IShellItem2)Marshal.GetUniqueObjectForIUnknown(shUnk);
                        try {
                            IntPtr pUnk = IntPtr.Zero;
                            _pSource.GetPropertyStoreForKeys(keyArray, (uint)nKeys, (GETPROPERTYSTOREFLAGS)flags, IID.IPropertyStore, out pUnk);
                            try {
                                _pStore = (IPropertyStore)Marshal.GetUniqueObjectForIUnknown(pUnk);
                            }
                            finally { Marshal.Release(pUnk); }
                        }
                        finally {
                            if (shUnk != IntPtr.Zero)
                            {
                                Marshal.Release(shUnk);
                            }
                        }
                    }
                    finally {
                        if (pidl != IntPtr.Zero)
                        {
                            Marshal.FreeCoTaskMem(pidl);
                        }
                    }
                }
                else
                {
                    string file;
                    path = path.Substring(path.LastIndexOf('\\') + 1);
                    if (path[0] == '.' || !path.Contains('.'))
                    {
                        file = Path.ChangeExtension("_Fake", path);
                    }
                    else
                    {
                        file = Path.GetFileName(path);
                    }
                    WIN32_FIND_DATA fd = new WIN32_FIND_DATA()
                    {
                        nFileSizeLow = 42
                    };
                    using (FakeFile f = new FakeFile(ref fd, file))
                    {
                        _pSource = (IShellItem2)f.GetShellItem();
                        IntPtr pUnk = IntPtr.Zero;
                        try
                        {
                            _pSource.GetPropertyStoreForKeys(keyArray, (uint)nKeys, (GETPROPERTYSTOREFLAGS)flags, IID.IPropertyStore, out pUnk);
                            _pStore = (IPropertyStore)Marshal.GetUniqueObjectForIUnknown(pUnk);
                        }
                        finally
                        {
                            if (pUnk != IntPtr.Zero)
                            {
                                Marshal.Release(pUnk);
                            }
                        }
                    }
                }
            }
            finally {
                if (keyArray != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(keyArray);
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Gets a <see cref="PropertyStore"/> containing the nominated properties using the specified <see cref="PropertyStore.GetFlags"/>
        /// </summary>
        /// <param name="flags">The flags to specify the PropertyStore retrieval method</param>
        /// <param name="keys">The <see cref="PropertyKey"/>s required in the store </param>
        /// <returns>The PropertyStore associated with this item containing the nominated properties</returns>
        public PropertyStore GetPropertyStoreForKeys(PropertyStore.GetFlags flags, params PropertyKey[] keys)
        {
            IntPtr arry = Marshal.AllocCoTaskMem(keys.Length + Marshal.SizeOf(typeof(PROPERTYKEY)));

            try {
                IntPtr ptr = arry;
                foreach (PropertyKey k in keys)
                {
                    PInvoke.MoveMemory(ptr, k.MarshalledPointer, Marshal.SizeOf(typeof(PROPERTYKEY)));
                    ptr += Marshal.SizeOf(typeof(PROPERTYKEY));
                }
                IntPtr pUnk;
                _pItem.GetPropertyStoreForKeys(arry, (uint)keys.Length, (GETPROPERTYSTOREFLAGS)flags, IID.IPropertyStore, out pUnk);
                PropertyStore store = new PropertyStore(pUnk);
                Marshal.Release(pUnk);
                return(store);
            }
            finally {
                Marshal.FreeCoTaskMem(arry);
            }
        }
コード例 #3
0
 public static T GetPropertyStoreForKeys <T>(this IShellItem2 psi, PROPERTYKEY[] rgKeys, GETPROPERTYSTOREFLAGS flags) where T : class
 {
     return((T)psi.GetPropertyStoreForKeys(rgKeys, unchecked ((uint)rgKeys.Length), flags, typeof(T).GUID));
 }