コード例 #1
0
        /// <summary>
        /// Generate a unique string for the ShellLink that can be used for equality checks.
        /// </summary>
        private static string ShellLinkToString(IShellLinkW shellLink)
        {
            var pathBuilder = new StringBuilder(Win32Constant.MAX_PATH);

            shellLink.GetPath(pathBuilder, pathBuilder.Capacity, null, SLGP.RAWPATH);

            string title = null;

            // Need to use the property store to get the title for the link.
            using (PROPVARIANT pv = new PROPVARIANT())
            {
                var  propStore = (IPropertyStore)shellLink;
                PKEY pkeyTitle = PKEY.Title;

                propStore.GetValue(ref pkeyTitle, pv);

                // PKEY_Title should be an LPWSTR if it's not empty.
                title = pv.GetValue() ?? "";
            }

            var argsBuilder = new StringBuilder(Win32Constant.INFOTIPSIZE);

            shellLink.GetArguments(argsBuilder, argsBuilder.Capacity);

            // Path and title should be case insensitive.
            // Shell treats arguments as case sensitive because apps can handle those differently.
            return(pathBuilder.ToString().ToUpperInvariant() + title.ToUpperInvariant() + argsBuilder.ToString());
        }
コード例 #2
0
        private static JumpItem GetJumpItemForShellObject(object shellObject)
        {
            var shellItem = shellObject as IShellItem2;
            var shellLink = shellObject as IShellLinkW;

            if (shellItem != null)
            {
                JumpPath path = new JumpPath
                {
                    Path = shellItem.GetDisplayName(SIGDN.DESKTOPABSOLUTEPARSING),
                };
                return(path);
            }

            if (shellLink != null)
            {
                var pathBuilder = new StringBuilder(Win32Constant.MAX_PATH);
                shellLink.GetPath(pathBuilder, pathBuilder.Capacity, null, SLGP.RAWPATH);
                var argsBuilder = new StringBuilder(Win32Constant.INFOTIPSIZE);
                shellLink.GetArguments(argsBuilder, argsBuilder.Capacity);
                var descBuilder = new StringBuilder(Win32Constant.INFOTIPSIZE);
                shellLink.GetDescription(descBuilder, descBuilder.Capacity);
                var iconBuilder = new StringBuilder(Win32Constant.MAX_PATH);
                int iconIndex;
                shellLink.GetIconLocation(iconBuilder, iconBuilder.Capacity, out iconIndex);
                var dirBuilder = new StringBuilder(Win32Constant.MAX_PATH);
                shellLink.GetWorkingDirectory(dirBuilder, dirBuilder.Capacity);

                JumpTask task = new JumpTask
                {
                    // Set ApplicationPath and IconResources, even if they're from the current application.
                    // This means that equivalent JumpTasks won't necessarily compare property-for-property.
                    ApplicationPath   = pathBuilder.ToString(),
                    Arguments         = argsBuilder.ToString(),
                    Description       = descBuilder.ToString(),
                    IconResourceIndex = iconIndex,
                    IconResourcePath  = iconBuilder.ToString(),
                    WorkingDirectory  = dirBuilder.ToString(),
                };

                using (PROPVARIANT pv = new PROPVARIANT())
                {
                    var  propStore = (IPropertyStore)shellLink;
                    PKEY pkeyTitle = PKEY.Title;

                    propStore.GetValue(ref pkeyTitle, pv);

                    // PKEY_Title should be an LPWSTR if it's not empty.
                    task.Title = pv.GetValue() ?? "";
                }

                return(task);
            }

            // Unsupported type?
            Debug.Assert(false);
            return(null);
        }
コード例 #3
0
ファイル: JumpList.cs プロジェクト: Yerongn/HandyControl
        private static JumpItem GetJumpItemForShellObject(object shellObject)
        {
            IShellItem2 shellItem  = shellObject as IShellItem2;
            IShellLinkW shellLinkW = shellObject as IShellLinkW;

            if (shellItem != null)
            {
                return(new JumpPath
                {
                    Path = shellItem.GetDisplayName((SIGDN)2147647488u)
                });
            }
            if (shellLinkW != null)
            {
                StringBuilder stringBuilder = new StringBuilder(260);
                shellLinkW.GetPath(stringBuilder, stringBuilder.Capacity, null, SLGP.RAWPATH);
                StringBuilder stringBuilder2 = new StringBuilder(1024);
                shellLinkW.GetArguments(stringBuilder2, stringBuilder2.Capacity);
                StringBuilder stringBuilder3 = new StringBuilder(1024);
                shellLinkW.GetDescription(stringBuilder3, stringBuilder3.Capacity);
                StringBuilder stringBuilder4 = new StringBuilder(260);
                int           iconResourceIndex;
                shellLinkW.GetIconLocation(stringBuilder4, stringBuilder4.Capacity, out iconResourceIndex);
                StringBuilder stringBuilder5 = new StringBuilder(260);
                shellLinkW.GetWorkingDirectory(stringBuilder5, stringBuilder5.Capacity);
                JumpTask jumpTask = new JumpTask
                {
                    ApplicationPath   = stringBuilder.ToString(),
                    Arguments         = stringBuilder2.ToString(),
                    Description       = stringBuilder3.ToString(),
                    IconResourceIndex = iconResourceIndex,
                    IconResourcePath  = stringBuilder4.ToString(),
                    WorkingDirectory  = stringBuilder5.ToString()
                };
                using (PROPVARIANT propvariant = new PROPVARIANT())
                {
                    IPropertyStore propertyStore = (IPropertyStore)shellLinkW;
                    PKEY           title         = PKEY.Title;
                    propertyStore.GetValue(ref title, propvariant);
                    jumpTask.Title = (propvariant.GetValue() ?? "");
                }
                return(jumpTask);
            }
            return(null);
        }
コード例 #4
0
ファイル: JumpList.cs プロジェクト: Yerongn/HandyControl
        private static string ShellLinkToString(IShellLinkW shellLink)
        {
            StringBuilder stringBuilder = new StringBuilder(260);

            shellLink.GetPath(stringBuilder, stringBuilder.Capacity, null, SLGP.RAWPATH);
            string text = null;

            using (PROPVARIANT propvariant = new PROPVARIANT())
            {
                IPropertyStore propertyStore = (IPropertyStore)shellLink;
                PKEY           title         = PKEY.Title;
                propertyStore.GetValue(ref title, propvariant);
                text = (propvariant.GetValue() ?? "");
            }
            StringBuilder stringBuilder2 = new StringBuilder(1024);

            shellLink.GetArguments(stringBuilder2, stringBuilder2.Capacity);
            return(stringBuilder.ToString().ToUpperInvariant() + text.ToUpperInvariant() + stringBuilder2.ToString());
        }
コード例 #5
0
ファイル: JumpList.cs プロジェクト: Yerongn/HandyControl
        private static IShellLinkW CreateLinkFromJumpTask(JumpTask jumpTask, bool allowSeparators)
        {
            if (string.IsNullOrEmpty(jumpTask.Title) && (!allowSeparators || !string.IsNullOrEmpty(jumpTask.CustomCategory)))
            {
                return(null);
            }
            IShellLinkW shellLinkW = (IShellLinkW)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("00021401-0000-0000-C000-000000000046")));
            IShellLinkW result;

            try
            {
                string path = JumpList._FullName;
                if (!string.IsNullOrEmpty(jumpTask.ApplicationPath))
                {
                    path = jumpTask.ApplicationPath;
                }
                shellLinkW.SetPath(path);
                if (!string.IsNullOrEmpty(jumpTask.WorkingDirectory))
                {
                    shellLinkW.SetWorkingDirectory(jumpTask.WorkingDirectory);
                }
                if (!string.IsNullOrEmpty(jumpTask.Arguments))
                {
                    shellLinkW.SetArguments(jumpTask.Arguments);
                }
                if (jumpTask.IconResourceIndex != -1)
                {
                    string pszIconPath = JumpList._FullName;
                    if (!string.IsNullOrEmpty(jumpTask.IconResourcePath))
                    {
                        if ((long)jumpTask.IconResourcePath.Length >= 260L)
                        {
                            return(null);
                        }
                        pszIconPath = jumpTask.IconResourcePath;
                    }
                    shellLinkW.SetIconLocation(pszIconPath, jumpTask.IconResourceIndex);
                }
                if (!string.IsNullOrEmpty(jumpTask.Description))
                {
                    shellLinkW.SetDescription(jumpTask.Description);
                }
                IPropertyStore propertyStore = (IPropertyStore)shellLinkW;
                using (PROPVARIANT propvariant = new PROPVARIANT())
                {
                    PKEY pkey = default(PKEY);
                    if (!string.IsNullOrEmpty(jumpTask.Title))
                    {
                        propvariant.SetValue(jumpTask.Title);
                        pkey = PKEY.Title;
                    }
                    else
                    {
                        propvariant.SetValue(true);
                        pkey = PKEY.AppUserModel_IsDestListSeparator;
                    }
                    propertyStore.SetValue(ref pkey, propvariant);
                }
                propertyStore.Commit();
                IShellLinkW shellLinkW2 = shellLinkW;
                shellLinkW = null;
                result     = shellLinkW2;
            }
            catch (Exception)
            {
                result = null;
            }
            finally
            {
                Utility.SafeRelease <IShellLinkW>(ref shellLinkW);
            }
            return(result);
        }
コード例 #6
0
        private static IShellLinkW CreateLinkFromJumpTask(JumpTask jumpTask, bool allowSeparators)
        {
            Debug.Assert(jumpTask != null);

            // Title is generally required.  If it's missing we need to treat this like a separator.
            // Everything else can still appear on separator elements,
            // but separators can only exist in the Tasks category.
            if (string.IsNullOrEmpty(jumpTask.Title))
            {
                if (!allowSeparators || !string.IsNullOrEmpty(jumpTask.CustomCategory))
                {
                    // Just treat this situation as an InvalidItem.
                    return(null);
                }
            }

            var link = (IShellLinkW)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(CLSID.ShellLink)));

            try
            {
                string appPath = _FullName;
                if (!string.IsNullOrEmpty(jumpTask.ApplicationPath))
                {
                    appPath = jumpTask.ApplicationPath;
                }

                link.SetPath(appPath);

                // This is optional.  Don't set it if the app hasn't explicitly requested it.
                if (!string.IsNullOrEmpty(jumpTask.WorkingDirectory))
                {
                    // Don't verify this.  It's possible that the directory doesn't exist now, but it will later.
                    // Shell handles this fine when we try to set an improperly formatted path.
                    link.SetWorkingDirectory(jumpTask.WorkingDirectory);
                }

                if (!string.IsNullOrEmpty(jumpTask.Arguments))
                {
                    link.SetArguments(jumpTask.Arguments);
                }

                // -1 is a sentinel value indicating not to use the icon.
                if (jumpTask.IconResourceIndex != -1)
                {
                    string resourcePath = _FullName;
                    if (!string.IsNullOrEmpty(jumpTask.IconResourcePath))
                    {
                        // Shell bug (Windows 7 595770): IShellLink doesn't correctly limit icon location path to MAX_PATH.
                        // It's really too bad we have to enforce this here.  When the shortcut gets
                        // serialized it streams the full string.  On deserialization it only retrieves
                        // MAX_PATH for this field leaving junk behind for subsequent gets, leading to data corruption.
                        // Because we don't want to allow the app to do create something that we know may
                        // be corrupt we have to enforce this ourselves.  If Shell fixes this later then
                        // we need to remove this check to let them handle this as they see fit.
                        // If they fix it by supporting longer paths, then we're artificially constraining this value...
                        if (jumpTask.IconResourcePath.Length >= Win32Constant.MAX_PATH)
                        {
                            // we could throw the exception here, but we're already globally catching everything.
                            return(null);
                        }
                        resourcePath = jumpTask.IconResourcePath;
                    }
                    link.SetIconLocation(resourcePath, jumpTask.IconResourceIndex);
                }

                if (!string.IsNullOrEmpty(jumpTask.Description))
                {
                    link.SetDescription(jumpTask.Description);
                }

                IPropertyStore propStore = (IPropertyStore)link;
                var            pv        = new PROPVARIANT();
                try
                {
                    PKEY pkey = default(PKEY);

                    if (!string.IsNullOrEmpty(jumpTask.Title))
                    {
                        pv.SetValue(jumpTask.Title);
                        pkey = PKEY.Title;
                    }
                    else
                    {
                        pv.SetValue(true);
                        pkey = PKEY.AppUserModel_IsDestListSeparator;
                    }

                    propStore.SetValue(ref pkey, pv);
                }
                finally
                {
                    Utilities.SafeDispose(ref pv);
                }

                propStore.Commit();

                IShellLinkW retLink = link;
                link = null;
                return(retLink);
            }
            catch (Exception)
            {
                // IShellLinkW::Set* methods tend to return E_FAIL when trying to set invalid data.
                // The create methods don't explicitly check for these kinds of errors.

                // If we aren't able to create the item for any reason just return null to indicate an invalid item.
                return(null);
            }
            finally
            {
                Utilities.SafeRelease(ref link);
            }
        }