|.netPlus / Samples / .NET|
This sample demonstrates how to read and write shortcut files from managed code. It includes definitions of the COM interfaces and coclasses needed. Included is also a more .NET friendly wrapper class, called ShellShortcut, that takes care of most of the dirty work. To demonstrate the usage of the ShellShortcut class, a simple shortcut editor form is included. To use shortcuts in your own code, simply include the files ShellLinkNative.cs and ShellShortcut.cs in your project.
Shortcuts are created and modified using a COM API, where the ShellLink coclass is the most important part. It implements the IShellLink interface (which exists in two versions, IShellLinkA for ANSI and IShellLinkW for Unicode) used to manipulate the shortcut itself, and the IPersistFile interface for opening and saving shortcut files. (It also implements the IShellLinkDataList interface to store extra data with shortcuts, and a number of other interfaces we don't care about).
There are two ways to get access to this coclass and its related interfaces in managed code. The first is to declare them all in a type library, then use the TlbImp tool to create a managed assembly from it. The second way, used in this sample, is to declare all of it ourselves in code. The advantage of doing it this way is that you get one less assembly to care about. But it also means you have to understand the details about COM interop and marshaling.
The coclass and the interfaces are marked with the ComImport and Guid attributes. The interfaces also need the InterfaceType attribute. Then some of the methods and method parameters need attributes as well to ensure correct marshaling. The .NET interop documentation explains all this fairly well.
There are some things that can't be done with the ShellShortcut wrapper class, but requires you to use the IShellLink interface directly. They are resolving targets (IShellLink::Resolve), setting relative paths (IShellLink::SetRelativePath) and handling PIDL shortcuts (IShellLink::GetIDList and IShellLink::SetIDList).