Reputation: 1058
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.
Upvotes: 0
Views: 1077
Reputation: 7744
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();
}
}
}
}
}
Upvotes: 1