I am building a custom installer. How can I create a shortcut to an executable in the start menu? This is what I've come up with so far:
string pathToExe = #"C:\Program Files (x86)\TestApp\TestApp.exe";
string commonStartMenuPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu);
string appStartMenuPath = Path.Combine(commonStartMenuPath, "Programs", "TestApp");
// TODO: create shortcut in appStartMenuPath
I'm targeting Windows 7.
Using the Windows Script Host (make sure to add a reference to the Windows Script Host Object Model, under References > COM tab):
using IWshRuntimeLibrary;
private static void AddShortcut()
{
string pathToExe = #"C:\Program Files (x86)\TestApp\TestApp.exe";
string commonStartMenuPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu);
string appStartMenuPath = Path.Combine(commonStartMenuPath, "Programs", "TestApp");
if (!Directory.Exists(appStartMenuPath))
Directory.CreateDirectory(appStartMenuPath);
string shortcutLocation = Path.Combine(appStartMenuPath, "Shortcut to Test App" + ".lnk");
WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutLocation);
shortcut.Description = "Test App Description";
//shortcut.IconLocation = #"C:\Program Files (x86)\TestApp\TestApp.ico"; //uncomment to set the icon of the shortcut
shortcut.TargetPath = pathToExe;
shortcut.Save();
}
By MSI setup, you can easily create Start Menu Shortcut for your application. But when it comes to custom installer setup, you need to write custom code to create All Programs shortcut. In C#, you can create shortcut using Windows Script Host library.
Note: To use Windows Script Host library, you need to add a reference under References > COM tab > Windows Script Host Object Model.
See this article for more info: http://www.morgantechspace.com/2015/01/create-start-menu-shortcut-all-programs-csharp.html
Create shortcut only for Current User:
string programs_path = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
string shortcutFolder = Path.Combine(programs_path, #"YourAppFolder\SampleApp");
if (!Directory.Exists(shortcutFolder))
{
Directory.CreateDirectory(shortcutFolder);
}
WshShellClass shellClass = new WshShellClass();
string settingsLink = Path.Combine(shortcutFolder, "Settings.lnk");
IWshShortcut shortcut = (IWshShortcut)shellClass.CreateShortcut(settingsLink);
shortcut.TargetPath = #"C:\Program Files\YourAppFolder\MyAppSettings.exe";
shortcut.IconLocation = #"C:\Program Files\YourAppFolder\settings.ico";
shortcut.Arguments = "arg1 arg2";
shortcut.Description = "Click to edit SampleApp settings";
shortcut.Save();
Create Shortcut for All Users:
You can get common profile path for All Users by using API function SHGetSpecialFolderPath.
using IWshRuntimeLibrary;
using System.Runtime.InteropServices;
---------------------------------
[DllImport("shell32.dll")]
static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder, bool fCreate);
const int CSIDL_COMMON_STARTMENU = 0x16;
public static void CreateShortcutForAllUsers()
{
StringBuilder allUserProfile = new StringBuilder(260);
SHGetSpecialFolderPath(IntPtr.Zero, allUserProfile, CSIDL_COMMON_STARTMENU, false);
//The above API call returns: C:\ProgramData\Microsoft\Windows\Start Menu
string programs_path = Path.Combine(allUserProfile.ToString(), "Programs");
string shortcutFolder = Path.Combine(programs_path, #"YourAppFolder\SampleApp");
if (!Directory.Exists(shortcutFolder))
{
Directory.CreateDirectory(shortcutFolder);
}
WshShellClass shellClass = new WshShellClass();
//Create Shortcut for Application Settings
string settingsLink = Path.Combine(shortcutFolder, "Settings.lnk");
IWshShortcut shortcut = (IWshShortcut)shellClass.CreateShortcut(settingsLink);
shortcut.TargetPath = #"C:\Program Files\YourAppFolder\MyAppSettings.exe";
shortcut.IconLocation = #"C:\Program Files\YourAppFolder\settings.ico";
shortcut.Arguments = "arg1 arg2";
shortcut.Description = "Click to edit SampleApp settings";
shortcut.Save();
}
This is pretty much the same as this question: Create shortcut on desktop C#.
To copy from that answer, you'll need to create the shortcut file yourself.
using (StreamWriter writer = new StreamWriter(appStartMenuPath + ".url"))
{
writer.WriteLine("[InternetShortcut]");
writer.WriteLine("URL=file:///" + pathToExe);
writer.WriteLine("IconIndex=0");
string icon = pathToExe.Replace('\\', '/');
writer.WriteLine("IconFile=" + icon);
}
This code is untested, of course, but it was accepted on that other question and it looks right.
I see another answer on that question that lists how to do it with the Windows API and some COM interop, but I'd be tempted to shy away from that and just use the above code if it works. It's more personal preference than anything, and I'd normally be all for using a pre-established API for this, but when the solution is this simple I'm just not sure how worth it that option really is. But for good measure, I believe this code should work. Again, of course, it's totally untested. And especially here where you're playing with things like this, make sure you understand each line before you execute it. I'd hate to see you mess up something on your system because of a blind following to code I posted.
WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(appStartMenuPath + ".lnk");
shortcut.Description = "Shortcut for TestApp";
shortcut.TargetPath = pathToExe;
shortcut.Save();
You will, of course, also need a reference to the "Windows Script Host Object Model," which can be found under "Add a Reference" then "COM."
Related
I am trying to make an app that creates a shortcut for selected program. When the program starts, it shows all programs in listbox and you can search for the program. How to create a shortcut from selected program inside listbox and name it like selected program. I used this code but I only created a shortcut for notepad.
Create shortcut on desktop C#
private void CreateShortcut()
{
object shDesktop = (object)"Desktop";
WshShell shell = new WshShell();
//string shortcutAddress = (string)shell.SpecialFolders.Item(ref shDesktop) + #"\Notepad.lnk";
string shortcutAddress = (string)shell.SpecialFolders.Item(ref shDesktop) + #"\Notepad.lnk";
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutAddress );
shortcut.Description = "New shortcut for a Notepad";
shortcut.Hotkey = "Ctrl+Shift+N";
shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolde r.System) + #"\notepad.exe";
shortcut.Save();
}
You can use CSharpLib. Download it here or, if you're using Visual Studio, enter Install-Package CSharpLib -Version 4.0.0 in Tools > NuGet Package Manager > Package Manager Console. It has a couple methods in the Shortcut class that you can use for shortcut manipulation. For example:
using CSharpLib;
Shortcut shortcut = new Shortcut();
shortcut.CreateShortcutToFile("target_file", "shortcut_file");
Change shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolde r.System) + #"\notepad.exe"; to shortcut.TargetPath = YourListBox.getSelected();
EDIT: if getSelected() doesn't work, try getSelectedItem()
I am trying to get my app create a shortcut on the desktop. The reason is because my app has some dependencies such ass external dlls and other and I prefer to have it in a folder and simply have a shortcut on my desktop rather than having all the files on my desktop or a folder containing everything.
It's the first time I am trying this. I believed it was simple and indeed it is so sorry if my question is a bit nooby.
My simple code looks like this:
string checkDesktopDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
if (!File.Exists(checkDesktopDir + "\\My app.url"))
{
ShortCutWithDependencies("My app");
}
private void ShortCutWithDependencies(string sAppName)
{
string deskDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
using (StreamWriter writer = new StreamWriter(deskDir + "\\" + sAppName + ".url"))
{
string app = Assembly.GetExecutingAssembly().Location;
MessageBox.Show(app);
writer.WriteLine("[InternetShortcut]");
writer.WriteLine("URL=" + app);
writer.WriteLine("IconIndex=0");
string icon = app.Replace('\\', '/');
writer.WriteLine("IconFile=" + icon);
writer.Flush();
}
}
However my app will never work. As soon as it get to the part it will need the dependencies to continue it will crash. More specific, when I use the methods imported via DLLImport such as bass.dll methods, it will simply crash. Of course I can't see anything in my output since the shortcut is a compiled .exe.
So my question is this; how do I create a full shortcut of my application?
Edit: updating example of dllimport
[DllImport("bass.dll")]
public static extern bool BASS_Start();
[DllImport("bass.dll")]
public static extern bool BASS_Init(int device, uint freq, uint flag,
IntPtr hParent, uint guid);
if (mp3ToPlay != string.Empty)
{
BASS_Start();
BASS_Init(-1, 44100, 0, IntPtr.Zero, 0);
BassHandle = BASS_StreamCreateFile(false, mp3ToPlay, 0, 0, 0x20000);
BASS_ChannelPlay(BassHandle, false);
PlayBackLength = BASS_ChannelGetLength(BassHandle, 0);
PlayBack = true;
}
Now I believe this is the problem. I am not sure though. The external dlls (bass.dll, Newtonsoft.Json.dll and Spotify.dll) have Copy to output directory set as Copy always and they are copied. The .exe will run fine and a shortcut created and sent to desktop manually will run fine as well.
Edit: Update 2 with Federico's example
Now this will work:
private void CreateShortcut()
{
object shDesktop = "Desktop";
WshShell shell = new WshShell();
string shortcutAddress = (string)shell.SpecialFolders.Item(ref shDesktop) + #"\iBlock.lnk";
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutAddress);
shortcut.Description = "New shortcut for a iBlock";
shortcut.Hotkey = "Ctrl+Shift+N";
shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + #"\iBlock\iBlock.exe";
shortcut.Save();
}
However there is a glitch here.
This part of my code
public string mp3Path = Directory.GetCurrentDirectory() + "\\mp3Directory";
if (!System.IO.File.Exists(mp3Path))
{
Directory.CreateDirectory(mp3Path);
}
Changing it to AppDomain.CurrentDomain.BaseDirectory will easily fix it.
Try creating the shortcut using the native COM Windows API, as explained in this answer: https://stackoverflow.com/a/4909475/3670737
At first, Project > Add Reference > COM > Windows Script Host Object Model.
using IWshRuntimeLibrary;
private void CreateShortcut()
{
object shDesktop = (object)"Desktop";
WshShell shell = new WshShell();
string shortcutAddress = (string)shell.SpecialFolders.Item(ref shDesktop) + #"\Notepad.lnk";
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutAddress);
shortcut.Description = "New shortcut for a Notepad";
shortcut.Hotkey = "Ctrl+Shift+N";
shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolders.System) + #"\notepad.exe";
shortcut.Save();
}
[Edit 1] Updated after Directory.GetCurrentDirectory() issue:
From the documentation: The current directory is distinct from the original directory, which is the one from which the process was started.
Your expected directory differs from the one returned by Directory.GetCurrentDirectory() because you actually start your process from a different directory when you use a shortcut (your Desktop). Directory.GetCurrentDirectory() returns the current working directory, which is the same of your assembly if you start it by opening the .exe file, but is the shortcut directory if you start it from the .lnk file.
In your scenario I'd use Assembly.GetExecutingAssembly().Location (check this answer for more info: https://stackoverflow.com/a/837501/3670737 )
If I understand correctly, it sounds like you might be better off just making an installer for your application. You can do this through Visual Studio, and it pretty much automates the process for you. Additionally, you might could try making your program a ClickOnce application with dependencies. I'd personally take the latter option.
I realize this isn't an especially thorough answer, but I feel like the question is a little unclear.
the project i am working on has to run on the windows startup i found the code, but what if the user don't wan't it to start on the startup!, do i have to tell the user to search for the sortcut and delete it, or simply make a button for that option, i know how to delete the file like this:
if(File.Exists(#"C:\Users\Maged\Desktop\remainder\WindowsFormsApplication1\bin\Debug\WindowsFormsApplication1.exe"))
{
File.Delete(#"C:\Users\Maged\Desktop\remainder\WindowsFormsApplication1\bin\Debug\WindowsFormsApplication1.exe");
}
i need to make the program searsh for MyStartupShortcut.lnk and delete it if exists.
here is my code on creating the shortcut:
void CreateStartupShortcut()
{
string startupFolder = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
WshShell shell = new WshShell();
string shortcutAddress = startupFolder + #"\MyStartupShortcut.lnk";
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutAddress);
shortcut.Description = "A startup shortcut. If you delete this shortcut from your computer, LaunchOnStartup.exe will not launch on Windows Startup";
shortcut.WorkingDirectory = Application.StartupPath;
shortcut.TargetPath = Application.ExecutablePath;
shortcut.Save();
}
i need to delete this file no matter the director is, any help?
Using shortcutAddress created as in the CreateStartupShortcut method the deletion of the shortcut should be achieved with the code:
if ( File.Exists(shortcutAddress) )
{
File.Delete(shortcutAddress );
}
How can I create a shortcut of power options with C# code?
This is my code:
WshShellClass wshShell = new WshShellClass();
IWshRuntimeLibrary.IWshShortcut MyShortcut;
MyShortcut = (IWshRuntimeLibrary.IWshShortcut)wshShell.CreateShortcut(#"C:\user\Administrator\power options.lnk");
MyShortcut.TargetPath = ???????;
MyShortcut.IconLocation = Application.StartupPath + ??????;
MyShortcut.Save();
Building on the answer from Moo-Juice, try the following:
WshShell shell = new WshShell();
string app = Path.Combine(Environment.SystemDirectory, "powercfg.cpl");
string linkPath = #"C:\PowerLink.lnk";
IWshShortcut link = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(linkPath);
link.TargetPath = app;
link.IconLocation = string.Format("{0},2", app);
link.Save();
The items in the control panel are stored in C:\windows\system32 with a .cpl extension. Therefore your target, for power options, should be:
C:\windows\system32\powercfg.cpl
Note: Do not use the hard-coded strings I have used here, use Environment.SystemDirectory to locate the directory appropriately.
I wanted to give my user an option for "Start with Windows". When user check this option it will place a shortcut icon into Startup folder (not in registry).
On Windows restart, it will load my app automatically.
How can this be done?
you can use the Enviroment.SpecialFolder enum, although depending on your requirements you might look at creating a windows service instead of an app that has to start on startup.
File.Copy("shortcut path...", Environment.GetFolderPath(Environment.SpecialFolder.Startup) + shorcutname);
edit:
File.Copy needs an origin file directory-path and the target directory-path to copy a file. The key in that snippet is Enviroment.GetFolderPath(Enviroment.SpecialFolder.Startup) which is getting the startup folder path where you want to copy your file to.
you could use the above code several ways. In case you've got an installer project for your app, you could run something like this on install. Another way could be when the app launches it checks if the shorcut exists there and puts one there if not (File.Exists()).
Here is a question about creating shortcuts in code also.
WshShell wshShell = new WshShell();
IWshRuntimeLibrary.IWshShortcut shortcut;
string startUpFolderPath =
Environment.GetFolderPath(Environment.SpecialFolder.Startup);
// Create the shortcut
shortcut =
(IWshRuntimeLibrary.IWshShortcut)wshShell.CreateShortcut(
startUpFolderPath + "\\" +
Application.ProductName + ".lnk");
shortcut.TargetPath = Application.ExecutablePath;
shortcut.WorkingDirectory = Application.StartupPath;
shortcut.Description = "Launch My Application";
// shortcut.IconLocation = Application.StartupPath + #"\App.ico";
shortcut.Save();
private void button2_Click(object sender, EventArgs e)
{
string pas = Application.StartupPath;
string sourcePath = pas;
string destinationPath = #"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup";
string sourceFileName = "filename.txt";//eny tipe of file
string sourceFile = System.IO.Path.Combine(sourcePath, sourceFileName);
string destinationFile = System.IO.Path.Combine(destinationPath);
if (!System.IO.Directory.Exists(destinationPath))
{
System.IO.Directory.CreateDirectory(destinationPath);
}
System.IO.File.Copy(sourceFile, destinationFile, true);
}