示例#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>
 /// Creates a shell item from the specified path.
 /// </summary>
 /// <param name="path">The path of the item to create</param>
 /// <param name="allowFake">Create the item, even if the specified file does not exist. Note that if a directory is supplied as part of the path, it <em>must</em> already exist</param>
 public ShellItem(string path, bool allowFake = false)
 {
     if (File.Exists(path) || Directory.Exists(path))
     {
         IBindCtx ctx = null;
         IntPtr   ppv;
         HRESULT  hr = PInvoke.SHCreateItemFromParsingName(path, ctx, IID.IShellItem, out ppv);
         hr.ThrowIfFailed();
         _pItem = (IShellItem2)Marshal.GetUniqueObjectForIUnknown(ppv);
         Marshal.Release(ppv);
     }
     else if (allowFake)
     {
         if (path.Contains('\\'))
         {
             string parent = Path.GetDirectoryName(path);
             if (!Directory.Exists(path))
             {
                 throw new DirectoryNotFoundException(parent);
             }
             string          fname = Path.GetFileName(path);
             WIN32_FIND_DATA wd    = new WIN32_FIND_DATA()
             {
                 cFileName = fname
             };
             using (FakeFile fake = new FakeFile(ref wd, fname)) {
                 IntPtr pparent = PInvoke.ILCreateFromPath(parent);
                 try {
                     IntPtr pidl = PInvoke.ILFindLastID(fake._ppidl);
                     IntPtr pUnk = IntPtr.Zero;
                     PInvoke.SHCreateItemWithParent(pparent, IntPtr.Zero, pidl, IID.IShellItem, out pUnk).ThrowIfFailed();
                     _pItem = (IShellItem2)Marshal.GetUniqueObjectForIUnknown(pUnk);
                     Marshal.Release(pUnk);
                 }
                 finally {
                     if (pparent != IntPtr.Zero)
                     {
                         Marshal.FreeCoTaskMem(pparent);
                     }
                 }
             }
         }
         else
         {
             WIN32_FIND_DATA wd = new WIN32_FIND_DATA()
             {
                 cFileName = path
             };
             using (FakeFile fake = new FakeFile(ref wd, path)) {
                 _pItem = (IShellItem2)fake.GetShellItem();
             }
         }
     }
     else
     {
         throw new FileNotFoundException();
     }
 }
示例#3
0
        /// <summary>
        /// Creates a <see cref="PropertyDescriptionList"/> based on properties defined for a particular file or file type.
        /// </summary>
        /// <param name="path">The path or extension of the file type you want the PropertyDescriptionList for</param>
        /// <param name="propListKey">This <see cref="PropertyKey"/> defines the usage of the properties defined in the PropertyDescriptionList. It will be one of the
        /// <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ff521713(v=vs.85).aspx">PropList</a> values</param>
        public PropertyDescriptionList(string path, PropertyKey propListKey)
        {
            IShellItem2 item = null;
            FakeFile    file = null;

            if (File.Exists(path))
            {
                IntPtr itemUnk;
                IntPtr pidl = ILCreateFromPath(Path.GetFullPath(path));
                SHCreateItemFromIDList(pidl, IID.IShellItem2, out itemUnk);
                item = (IShellItem2)Marshal.GetUniqueObjectForIUnknown(itemUnk);
                Marshal.Release(itemUnk);
                Marshal.FreeCoTaskMem(pidl);
            }
            else
            {
                string name;
                path = path.Substring(path.LastIndexOf('\\') + 1);
                if (path[0] == '.' || !(path.Contains('.')))
                {
                    name = Path.ChangeExtension("_fakeFile", path);
                }
                else
                {
                    name = Path.GetFileName(path);
                }
                WIN32_FIND_DATA fd = new WIN32_FIND_DATA()
                {
                    dwFileAttributes = FileAttributes.Normal, nFileSizeLow = 42
                };
                file = new FakeFile(ref fd, name);
                item = (IShellItem2)file.GetShellItem();
            }
            try {
                IntPtr ppUnk = IntPtr.Zero;;
                item.GetPropertyDescriptionList(propListKey.MarshalledPointer, IID.IProperyDescriptionList, out ppUnk);
                _propList = (IPropertyDescriptionList)Marshal.GetUniqueObjectForIUnknown(ppUnk);
                Marshal.Release(ppUnk);
            }
            finally {
                if (item != null)
                {
                    Marshal.FinalReleaseComObject(item);
                }
                if (file != null)
                {
                    file.Dispose();
                }
            }
        }
示例#4
0
 /// <summary>
 /// Loads a <see cref="PropertyStore"/> for the specified file or extension. 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="flags">The <see cref="GetFlags"/> indicating the type of store to load</param>
 public PropertyStore(string path, GetFlags flags)
 {
     if (File.Exists(path))
     {
         IntPtr pidl = ILCreateFromPath(Path.GetFullPath(path));
         try {
             IntPtr  shUnk = IntPtr.Zero;
             HRESULT hr    = SHCreateItemFromIDList(pidl, IID.IShellItem2, out shUnk);
             _pSource = (IShellItem2)Marshal.GetUniqueObjectForIUnknown(shUnk);
             try {
                 IntPtr pUnk = IntPtr.Zero;
                 _pSource.GetPropertyStore((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
         };
         FakeFile f = new FakeFile(ref fd, file);
         _pSource = (IShellItem2)f.GetShellItem();
         IntPtr pUnk = IntPtr.Zero;
         try {
             _pSource.GetPropertyStore((GETPROPERTYSTOREFLAGS)flags, IID.IPropertyStore, out pUnk);
             _pStore = (IPropertyStore)Marshal.GetUniqueObjectForIUnknown(pUnk);
         }
         finally {
             if (pUnk != IntPtr.Zero)
             {
                 Marshal.Release(pUnk);
             }
         }
     }
 }