Creating application shortcut in a directory

C#.NetFile IoShortcut

C# Problem Overview


How do you create an application shortcut (.lnk file) in C# or using the .NET framework?

The result would be a .lnk file to the specified application or URL.

C# Solutions


Solution 1 - C#

It's not as simple as I'd have liked, but there is a great class call ShellLink.cs at vbAccelerator

This code uses interop, but does not rely on WSH.

Using this class, the code to create the shortcut is:

private static void configStep_addShortcutToStartupGroup()
{
    using (ShellLink shortcut = new ShellLink())
    {
	    shortcut.Target = Application.ExecutablePath;
	    shortcut.WorkingDirectory = Path.GetDirectoryName(Application.ExecutablePath);
	    shortcut.Description = "My Shorcut Name Here";
	    shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
	    shortcut.Save(STARTUP_SHORTCUT_FILEPATH);
    }
}

Solution 2 - C#

Nice and clean. (.NET 4.0)

Type t = Type.GetTypeFromCLSID(new Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8")); //Windows Script Host Shell Object
dynamic shell = Activator.CreateInstance(t);
try{
	var lnk = shell.CreateShortcut("sc.lnk");
	try{
		lnk.TargetPath = @"C:\something";
		lnk.IconLocation = "shell32.dll, 1";
		lnk.Save();
	}finally{
		Marshal.FinalReleaseComObject(lnk);
	}
}finally{
	Marshal.FinalReleaseComObject(shell);
}

That's it, no additional code needed. CreateShortcut can even load shortcut from file, so properties like TargetPath return existing information. http://msdn.microsoft.com/en-us/library/f5y78918%28v=vs.84%29.aspx">Shortcut object properties.

Also possible this way for versions of .NET unsupporting dynamic types. (.NET 3.5)

Type t = Type.GetTypeFromCLSID(new Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8")); //Windows Script Host Shell Object
object shell = Activator.CreateInstance(t);
try{
	object lnk = t.InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shell, new object[]{"sc.lnk"});
	try{
		t.InvokeMember("TargetPath", BindingFlags.SetProperty, null, lnk, new object[]{@"C:\whatever"});
		t.InvokeMember("IconLocation", BindingFlags.SetProperty, null, lnk, new object[]{"shell32.dll, 5"});
		t.InvokeMember("Save", BindingFlags.InvokeMethod, null, lnk, null);
	}finally{
		Marshal.FinalReleaseComObject(lnk);
	}
}finally{
	Marshal.FinalReleaseComObject(shell);
}

Solution 3 - C#

I found something like this:

private void appShortcutToDesktop(string linkName)
{
    string deskDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

    using (StreamWriter writer = new StreamWriter(deskDir + "\\" + linkName + ".url"))
    {
        string app = System.Reflection.Assembly.GetExecutingAssembly().Location;
        writer.WriteLine("[InternetShortcut]");
        writer.WriteLine("URL=file:///" + app);
        writer.WriteLine("IconIndex=0");
        string icon = app.Replace('\\', '/');
        writer.WriteLine("IconFile=" + icon);
        writer.Flush();
    }
}

Original code at sorrowman's article "url-link-to-desktop"

Solution 4 - C#

Donwload IWshRuntimeLibrary

You also need to import of COM library IWshRuntimeLibrary. Right click on your project -> add reference -> COM -> IWshRuntimeLibrary -> add and then use the following code snippet.

private void createShortcutOnDesktop(String executablePath)
{
	// Create a new instance of WshShellClass

	WshShell lib = new WshShellClass();
	// Create the shortcut

	IWshRuntimeLibrary.IWshShortcut MyShortcut;


	// Choose the path for the shortcut
	string deskDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
	MyShortcut = (IWshRuntimeLibrary.IWshShortcut)lib.CreateShortcut(@deskDir+"\\AZ.lnk");


	// Where the shortcut should point to

	//MyShortcut.TargetPath = Application.ExecutablePath;
	MyShortcut.TargetPath = @executablePath;


	// Description for the shortcut

	MyShortcut.Description = "Launch AZ Client";
 
	StreamWriter writer = new StreamWriter(@"D:\AZ\logo.ico");
	Properties.Resources.system.Save(writer.BaseStream);
	writer.Flush();
	writer.Close();
	// Location for the shortcut's icon           

	MyShortcut.IconLocation = @"D:\AZ\logo.ico";
	

	// Create the shortcut at the given path

	MyShortcut.Save();

}

Solution 5 - C#

After surveying all possibilities I found on SO I've settled on ShellLink:

//Create new shortcut
using (var shellShortcut = new ShellShortcut(newShortcutPath)
{
     Path = path
     WorkingDirectory = workingDir,
     Arguments = args,
     IconPath = iconPath,
     IconIndex = iconIndex,
     Description = description,
})
{
    shellShortcut.Save();
}

//Read existing shortcut
using (var shellShortcut = new ShellShortcut(existingShortcut))
{
    path = shellShortcut.Path;
    args = shellShortcut.Arguments;
    workingDir = shellShortcut.WorkingDirectory;
    ...
}

Apart of being simple and effective, the author (Mattias Sjögren, MS MVP) is some sort of COM/PInvoke/Interop guru, and perusing his code I believe it is more robust than the alternatives.

It should be mentioned that shortcut files can also be created by several commandline utilities (which in turn can be easily invoked from C#/.NET). I never tried any of them, but I'd start with NirCmd (NirSoft have SysInternals-like quality tools).

Unfortunately NirCmd can't parse shortcut files (only create them), but for that purpose TZWorks lp seems capable. It can even format its output as csv. lnk-parser looks good too (it can output both HTML and CSV).

Solution 6 - C#

Similar to IllidanS4's answer, using the Windows Script Host proved the be the easiest solution for me (tested on Windows 8 64 bit).

However, rather than importing the COM type manually through code, it is easier to just add the COM type library as a reference. Choose References->Add Reference..., COM->Type Libraries and find and add "Windows Script Host Object Model".

This imports the namespace IWshRuntimeLibrary, from which you can access:

WshShell shell = new WshShell();
IWshShortcut link = (IWshShortcut)shell.CreateShortcut(LinkPathName);
link.TargetPath=TargetPathName;
link.Save();

Credit goes to Jim Hollenhorst.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCharley RathkopfView Question on Stackoverflow
Solution 1 - C#Charley RathkopfView Answer on Stackoverflow
Solution 2 - C#IS4View Answer on Stackoverflow
Solution 3 - C#AnurajView Answer on Stackoverflow
Solution 4 - C#AZ_View Answer on Stackoverflow
Solution 5 - C#Ohad SchneiderView Answer on Stackoverflow
Solution 6 - C#Steven JeurisView Answer on Stackoverflow