0

Is it possible to DRAG a Windows Desktop icon onto a forms listView. Dragging a desktop icon anywhere besides the desktop doesn't seem permissible. The listView's drag/drop or mouse events aren't triggered when dragging the icon over the listView.

I'm trying to ascertain the path to the appropriately linked file from the shortcut itself. I think I can get the linking file info from the desktop's .lnk file and use it but it seems the only way I can do that is with the user doing a copy/paste rather than drag and drop.

EDIT: To be clear - when dragging a Windows Shortcut over the "AllowDrop = true" enabled control, the associated drag/drop events are not triggered. I already know how to get the data that I need from the link file.

RUNNING AS ADMINISTRATOR: The answer below has been accepted as correct because as the poster states in his comments and mentioned elsewhere, if running "As Administrator", drag&drop won't work in this scenario.

David
  • 958
  • 2
  • 12
  • 29
  • Enable `AllowDrop` and, in `ListView_DragEnter`, `if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;`. Then handle the file drop in `ListView_DragDrop`. The icon's path is referenced in Shell link properties. If could be a file or the icon index contained in an executable. The executable can be a different file than the target one. For example, it could the program that opens the file or an icon in shell32.dll etc. – Jimi Jul 23 '19 at 05:37
  • After you got the link (`string link = e.Data.GetData(DataFormats.FileDrop).First();` you can get more info like [so](https://stackoverflow.com/questions/9414152/get-target-of-shortcut-folder) – TaW Jul 23 '19 at 07:16
  • @TaW It's quite probable that the methods shown in that question won't work. Maybe this question: [How to use Shell32 within a C# application?](https://stackoverflow.com/questions/5708434/how-to-use-shell32-within-a-c-sharp-application/18894720), the *problem* is mentioned. Also, the icon can be derived from the associated program (the program that opens the file), so you'll have to use `AssocQueryString` to get the associated app's executable and get the icon from there. It could also be a pointer to an `ItemIdList`. – Jimi Jul 23 '19 at 09:06
  • They work fine here. Also: I don't think he cares about Icons. He just want to drop a link onto a listview and see the program or file or folder behind the link. Your hints and the linked post work just fine here (w10, 64bit, VS2017).. – TaW Jul 23 '19 at 12:08
  • @TaW Yep, I rushed through the question and `icon` stuck. Probably, just the file name is needed -- Which post? The one that casts `ShellLinkObject` or the one that uses `Type.GetTypeFromProgID("Shell.Application");` (I actually use the Shell interfaces directly, not a `Shell32` reference, which brings up `Microsoft Shell Controls and Automation`. There are many posts stating the former doesn't work on Windows 8+). – Jimi Jul 23 '19 at 13:02
  • I meant the (tiny) link at the end of my 1st post. – TaW Jul 23 '19 at 14:09

1 Answers1

1

The OP was running Visual Studio in administrator mode, therefore the program being run was run in administrator mode as well. According to this question, due to desktop and the application running at different privilege levels, you should not be able to drag and drop between the desktop and the application.

I am not sure on why the OP was able to drop files in from what I assume was a normal Windows File Explorer as technically that should suffer from the same issue.


For simplicity I just used an empty Form with the property AllowDrop equal to true and the events, DragDrop linked to the method DnDExample_DragDrop and DragOver linked to the method DnDExample_DragOver. I also imported Windows Script Host Object Model into the project by right clicking on the project, clicking add reference, going to the COM tab, finding the reference on there and then importing it.

Enough about the set up.


A simple way would be to use the DragOver and Drop events on your list. For simplicity, I just used a form.

In the drag over, you want to check the file types of the files being dragged on to the area you are meant to drop it. If all the files are the correct type, the shortcut type, then you want to allow the drop.

On the drop, you can then handle the logic of what you want to happen. For my example, I just print the shortcut file paths out and their target.

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();
                }
            }
        }
    }
}
Dan
  • 7,286
  • 6
  • 49
  • 114
  • I created a project and copy/pasted your code. When run, the events are NOT even triggered when dragging a Windows Shortcut over the form. The event IS triggered when dragging a file over it. – David Jul 24 '19 at 01:15
  • @David That's strange. Whilst I imagine this won't affect it, what version of Windows are you running? – Dan Jul 24 '19 at 06:48
  • @David Also, when the event is triggered with a normal file, does it show the invalid cursor or does it allow you to drop it? – Dan Jul 24 '19 at 06:49
  • Download the solution from [here](http://www.aquacomm.com.au/downloads/DragDrop2.zip). I've tried a couple of Win10 releases with the same result. – David Jul 25 '19 at 00:40
  • @David So the weird thing is, after downloading and running without changing anything, for me that works as expected which makes it a little hard for me to debug. Sorry about that. A quick question, if you open file explorer, navigate to the desktop folder, and then drag one of the shortcuts over the window, does it work as expected? – Dan Jul 25 '19 at 06:57
  • @David Also, I found this similar [question](https://stackoverflow.com/questions/27191297/file-drag-and-drop-not-working-on-listbox). Try running the exe directly from the debug folder. See if it works then. You are not running Visual Studio as administrator are you? As if I am running visual studio as Admin, dragging things from my desktop do not trigger the events – Dan Jul 25 '19 at 07:02
  • @David If you are running as administrator, according to [this question](https://stackoverflow.com/questions/8239271/uac-elevation-does-not-allow-drag-and-drop) and [this question](https://stackoverflow.com/questions/2833709/c-sharp-drag-drop-does-not-work-on-windows-7), you will not be able to drag and drop from the desktop – Dan Jul 25 '19 at 07:05