Put application in startup

In this post I’ll show how you can put your application in Windows Startup using C#. One of the solutions to put yout application in Windows Startup is putting shortcut of your application in the startup folder of Windows.

To do it manually (to give it a try), you can follow the instructios shared in Add an app to run automatically at startup in Windows 10:

  1. Press Win + R keys to open Run window
  2. Type shell:startup and press Enter
  3. Right click and Add new shortcut to your application.

Now if you sign-out from windows and sign in again, you will see the application will run at start up.

In this example, I’ll do above using two different ways:
1. Creating a Setup project to install the application and put in startup
2. Adding the shortcut to the startup foler using code

Later in this post I’ll show how you can do it using a C# application.

How to add the application to startup folder using C

You can use either of the following options to add an application to the startup folder using C#:

  • Put application in startup folder using an installer
  • Put application is startup folder using code

Example 1 – Put application in startup folder using an installer

Follow these steps:

  1. Download and install Microsoft Visual Studio Installer Projects extension. (VS2022, VS2017 & VS2019)
  2. Add a new Windows Forms Project
  3. Add a new Setup project to the solution
  4. Right click on the Setup project → Add → Project Output, then select primary output from your windows forms project.
  5. Right click on the Setup project → View → File System
  6. Right click on the FileSystem → Add Special Folder → User’s Startup Folder
  7. Right click In the User’s Startup Folder (in the list with two columns, name and type) → Create New Shortcut → Browse Application Folder and choose Primary output from the Windows Application and click OK.
    enter image description here
  8. Edit the name of the shortcut or set an icon for it.
  9. Rebuild all the projects (including the setup).
  10. Install the setup (approve if requested to modify system)
  11. if you sign out and sign in again, you will see the application is in startup folder.

To verify and see if the app is inside the folder:

  1. Press Win + R keys to open Run window
  2. Type shell:startup and press Enter
  3. See the shortcut of your application in the startup folder.

Example 2 – Put application is startup folder using code

Follow these steps:

  1. Create Windows Forms Application
  2. Drop a CheckBox on the form and change its text to “Run at startup of Windows”
  3. Drop a Button on the form and change its text to “Save”.
  4. Add a the following code to the project (Thanks to the ref1, ref2):
    using System;
    using System.Runtime.InteropServices;
    using System.Text;
    
    [ComImport]
    [Guid("00021401-0000-0000-C000-000000000046")]
    class ShellLink
    {
    }
    
    /// <summary>The IShellLink interface allows Shell links to be created, modified, and resolved</summary>
    [ComImport()]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214F9-0000-0000-C000-000000000046")]
    interface IShellLinkW
    {
        /// <summary>Retrieves the path and file name of a Shell link object</summary>
        void GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags);
        /// <summary>Retrieves the list of item identifiers for a Shell link object</summary>
        void GetIDList(out IntPtr ppidl);
        /// <summary>Sets the pointer to an item identifier list (PIDL) for a Shell link object.</summary>
        void SetIDList(IntPtr pidl);
        /// <summary>Retrieves the description string for a Shell link object</summary>
        void GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
        /// <summary>Sets the description for a Shell link object. The description can be any application-defined string</summary>
        void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
        /// <summary>Retrieves the name of the working directory for a Shell link object</summary>
        void GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
        /// <summary>Sets the name of the working directory for a Shell link object</summary>
        void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
        /// <summary>Retrieves the command-line arguments associated with a Shell link object</summary>
        void GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
        /// <summary>Sets the command-line arguments for a Shell link object</summary>
        void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
        /// <summary>Retrieves the hot key for a Shell link object</summary>
        void GetHotkey(out short pwHotkey);
        /// <summary>Sets a hot key for a Shell link object</summary>
        void SetHotkey(short wHotkey);
        /// <summary>Retrieves the show command for a Shell link object</summary>
        void GetShowCmd(out int piShowCmd);
        /// <summary>Sets the show command for a Shell link object. The show command sets the initial show state of the window.</summary>
        void SetShowCmd(int iShowCmd);
        /// <summary>Retrieves the location (path and index) of the icon for a Shell link object</summary>
        void GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
            int cchIconPath, out int piIcon);
        /// <summary>Sets the location (path and index) of the icon for a Shell link object</summary>
        void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
        /// <summary>Sets the relative path to the Shell link object</summary>
        void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
        /// <summary>Attempts to find the target of a Shell link, even if it has been moved or renamed</summary>
        void Resolve(IntPtr hwnd, int fFlags);
        /// <summary>Sets the path and file name of a Shell link object</summary>
        void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
    }
    
  5. Doubleclick on the Button and add the following code to the event handler
    private void button1_Click(object sender, EventArgs e)
    {
        var startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
        var exeFilePath = Application.ExecutablePath;
        var appName = Path.GetFileNameWithoutExtension(exeFilePath);
        var lnkFilePath = Path.Combine(startupPath, $"{appName}.lnk");
        if (checkBox1.Checked)
        {
            if (File.Exists(lnkFilePath))
                return;
            var lnk = (IShellLinkW)new ShellLink();
            lnk.SetPath(exeFilePath);
            lnk.SetDescription("My application!");
            lnk.SetIconLocation(exeFilePath, 0);
            var file = (IPersistFile)lnk;
            file.Save(lnkFilePath, false);
        }
        else
        {
            if (File.Exists(lnkFilePath))
                File.Delete(lnkFilePath);
        }
    }
    
  6. Double click on the Form and add the following code:
    private void Form2_Load(object sender, EventArgs e)
    {
        checkBox1.Checked = IsInStartup();
    }
    bool IsInStartup()
    {
        var startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
        var exeFilePath = Application.ExecutablePath;
        var appName = Path.GetFileNameWithoutExtension(exeFilePath);
        var lnkFilePath = Path.Combine(startupPath, $"{appName}.lnk");
        if (File.Exists(lnkFilePath))
            return true;
        return false;
    }
    
  7. Run the application and you can put the checkmark or remove it to save/remove the application in/from startup:
    enter image description here

You May Also Like

About the Author: Reza Aghaei

I’ve been a .NET developer since 2004. During these years, as a developer, technical lead and architect, I’ve helped organizations and development teams in design and development of different kind of applications including LOB applications, Web and Windows application frameworks and RAD tools. As a teacher and mentor, I’ve trained tens of developers in C#, ASP.NET MVC and Windows Forms. As an interviewer I’ve helped organizations to assess and hire tens of qualified developers. I really enjoy learning new things, problem solving, knowledge sharing and helping other developers. I'm usually active in .NET related tags in stackoverflow to answer community questions. I also share technical blog posts in my blog as well as sharing sample codes in GitHub.

Leave a Reply

Your email address will not be published. Required fields are marked *