将 Windows 桌面快捷方式拖放到 listView

Posted

技术标签:

【中文标题】将 Windows 桌面快捷方式拖放到 listView【英文标题】:Drag and Drop a Windows Desktop shortcut to a listView 【发布时间】:2019-12-01 01:01:13 【问题描述】:

是否可以将 Windows 桌面图标拖到表单列表视图上。似乎不允许将桌面图标拖动到桌面以外的任何地方。将图标拖到 listView 上时,不会触发 listView 的拖放或鼠标事件。

我正在尝试从快捷方式本身确定适当链接文件的路径。我想我可以从桌面的 .lnk 文件中获取链接文件信息并使用它,但似乎我能做到这一点的唯一方法是让用户进行复制/粘贴而不是拖放。

编辑: 需要明确的是 - 在启用“AllowDrop = true”的控件上拖动 Windows 快捷方式时,不会触发相关的拖放事件。我已经知道如何从链接文件中获取我需要的数据了。

以管理员身份运行: 下面的答案被认为是正确的,因为正如发帖人在他的 cmets 中所说并在其他地方提到的那样,如果运行“以管理员身份”,拖放将无法在 这种 场景中工作。

【问题讨论】:

启用AllowDropListView_DragEnterif (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;。然后处理ListView_DragDrop中的文件放置。 Shell 链接属性中引用了图标的路径。如果可以是可执行文件中包含的文件或图标索引。可执行文件可以是与目标文件不同的文件。比如打开文件的程序或者shell32.dll中的图标等。 获得链接后(string link = e.Data.GetData(DataFormats.FileDrop).First();,您可以获得更多信息,例如so @TaW 该问题中显示的方法很可能不起作用。也许这个问题:How to use Shell32 within a C# application?,提到了问题。此外,图标可以从关联程序(打开文件的程序)派生,因此您必须使用AssocQueryString 来获取关联应用程序的可执行文件并从那里获取图标。它也可以是指向ItemIdList 的指针。 他们在这里工作得很好。另外:我认为他不关心图标。他只想将链接放到列表视图上,然后查看链接后面的程序或文件或文件夹。您的提示和链接的帖子在这里工作得很好(w10、64bit、VS2017).. @TaW 是的,我匆匆回答了这个问题,icon 卡住了。可能只需要文件名——哪个帖子?使用ShellLinkObject 的那个或使用Type.GetTypeFromProgID("Shell.Application"); 的那个(我实际上直接使用Shell 接口,而不是Shell32 引用,这会带来Microsoft Shell Controls and Automation。有很多帖子说明前者不起作用Windows 8+)。 【参考方案1】:

OP 在管理员模式下运行 Visual Studio,因此正在运行的程序也在管理员模式下运行。根据这个question,由于桌面和应用程序运行在不同的权限级别,你应该不能在桌面和应用程序之间拖放。

我不确定为什么 OP 能够从我认为是普通的 Windows 文件资源管理器的文件中放入文件,因为从技术上讲应该会遇到同样的问题。


为简单起见,我只使用了一个空表单,其属性AllowDrop 等于true,事件DragDrop 链接到方法DnDExample_DragDropDragOver 链接到方法DnDExample_DragOver。我还将Windows Script Host Object Model 导入到项目中,方法是右键单击项目,单击添加引用,转到 COM 选项卡,在那里找到引用,然后将其导入。

关于设置已经足够了。


一种简单的方法是使用列表中的 DragOver 和 Drop 事件。为简单起见,我只使用了一个表单。

在拖动过程中,您要检查被拖动到您要放置它的区域的文件的文件类型。如果所有文件都是正确的类型,快捷方式类型,那么你要允许放置。

在放置时,您可以处理您想要发生的事情的逻辑。对于我的示例,我只是将快捷方式文件路径及其目标打印出来。

using System;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using IWshRuntimeLibrary;

namespace DragAndDropShortcut

    public partial class DnDExample : Form
    
        private readonly WshShell shell = new WshShell();
        public DnDExample()
        
            InitializeComponent();
        

        private void DnDExample_DragOver(object sender, DragEventArgs e)
        
            // This checks that each file being dragged over is a .lnk file.
            // If it is not, it will show the invalid cursor thanks to some
            // e.Effect being set to none by default.
            bool dropEnabled = true;
            if (e.Data.GetDataPresent(DataFormats.FileDrop, true))
            
                if (e.Data.GetDataPresent(DataFormats.FileDrop, true) &&
                    e.Data.GetData(DataFormats.FileDrop, true) is string[] filePaths &&
                    filePaths.Any(filePath => Path.GetExtension(filePath)?.ToLowerInvariant() != ".lnk"))
                
                    dropEnabled = false;
                
            
            else
            
                dropEnabled = false;
            

            if (dropEnabled)
            
                // Set the effect to copy so we can drop the item
                e.Effect = DragDropEffects.Copy;
            
        

        private void DnDExample_DragDrop(object sender, DragEventArgs e)
        
            if (e.Data.GetDataPresent(DataFormats.FileDrop) &&
                e.Data.GetData(DataFormats.FileDrop, true) is string[] filePaths)
            
                // Print out the path and target of each shortcut file dropped on
                foreach (string filePath in filePaths)
                
                    IWshShortcut link = (IWshShortcut)shell.CreateShortcut(filePath); //Link the interface to our shortcut
                    Console.WriteLine(filePath);
                    Console.WriteLine(link.TargetPath); //Show the target in a MessageBox using IWshShortcut
                    Console.WriteLine();
                
            
        
    

【讨论】:

我创建了一个项目并复制/粘贴了您的代码。运行时,在窗体上拖动 Windows 快捷方式时甚至不会触发事件。拖动文件时触发该事件。 @David 这很奇怪。虽然我想这不会影响它,但您运行的是哪个版本的 Windows? @David 另外,当使用普通文件触发事件时,它会显示无效光标还是允许您删除它? 从here下载解决方案。我已经尝试了几个 Win10 版本,结果相同。 @David 所以奇怪的是,在下载并运行而不更改任何内容之后,对我来说,它按预期工作,这让我很难调试。对于那个很抱歉。一个快速的问题,如果您打开文件资源管理器,导航到桌面文件夹,然后将其中一个快捷方式拖到窗口上,它是否按预期工作?

以上是关于将 Windows 桌面快捷方式拖放到 listView的主要内容,如果未能解决你的问题,请参考以下文章

windows xp怎样将经常使用的程序像windows7那样放在快速启动栏下呢?

拖放动态创建的快捷方式

拖放到桌面图标

拖放到桌面/资源管理器

QQ联系人怎么放在桌面上

咏南CS开发框架新的界面风格