We have a network drive full of shortcuts (.lnk files) that point to folders and I need to traverse them programmatically in a C# Winforms app.
What practical options do I have?
We have a network drive full of shortcuts (.lnk files) that point to folders and I need to traverse them programmatically in a C# Winforms app.
What practical options do I have?
Add IWshRuntimeLibrary as a reference to your project. Add Reference, COM tab, Windows Scripting Host Object Model.
Here is how I get the properties of a shortcut:
IWshRuntimeLibrary.IWshShell wsh = new IWshRuntimeLibrary.WshShellClass();
IWshRuntimeLibrary.IWshShortcut sc = (IWshRuntimeLibrary.IWshShortcut)wsh.CreateShortcut(filename);
The shortcut object "sc" has a TargetPath property.
If you do not wish to reference COM, and distribute the Interop.IWshRuntimeLibrary.dll with your product (remembering Jay Riggs "Embed Interop Types": False)
You can use the new dynamic COM instead.
private void Window_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
dynamic shortcut;
dynamic windowsShell;
try
{
var file = files[0];
if (Path.GetExtension(file)?.Equals(".lnk",StringComparison.OrdinalIgnoreCase) == true)
{
Type shellObjectType = Type.GetTypeFromProgID("WScript.Shell");
windowsShell = Activator.CreateInstance(shellObjectType);
shortcut = windowsShell.CreateShortcut(file);
file = shortcut.TargetPath;
// Release the COM objects
shortcut = null;
windowsShell = null;
}
//
// <use file>...
//
}
finally
{
// Release the COM objects
shortcut = null;
windowsShell = null;
}
}
}
I know it is not the correct way and that lnk file structures can change etc., but this is what I do:
private static string LnkToFile(string fileLink)
{
string link = File.ReadAllText(fileLink);
int i1 = link.IndexOf("DATA\0");
if (i1 < 0)
return null;
i1 += 5;
int i2 = link.IndexOf("\0", i1);
if (i2 < 0)
return link.Substring(i1);
else
return link.Substring(i1, i2 - i1);
}
As far as I am aware you can have .NET generate classes conforming to each of these interfaces for you using the "Add Reference" dialog box.
The IShellLink interface lets you manipulate .lnk files, though it's a bit of a pain to use from C#.
This article has some code implementing the necessary interop gubbins.
Update
You can find the code from the article here but the page doesn't seem to work in Firefox. It does work in IE.