Two ways to have your C# application run during Windows start-up

The simplest method, in my opinion, relies on the Windows registry.

using Microsoft.Win32;

namespace WindowsStartupTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            checkBoxRegistry.Checked = (registryKey().GetValue(Application.ProductName) != null);

        }
        private RegistryKey registryKey()
        {
            return Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run")!;
        }
        private void checkBoxRegistry_Click(object sender, EventArgs e)
        {
            if (checkBoxRegistry.Checked)
            {
                registryKey().SetValue(Application.ProductName, Application.ExecutablePath);
            }
            else
            {
                registryKey().DeleteValue(Application.ProductName, false);
            }
        }
    }
}

Another method is to add an application shortcut to the Windows Startup folder.

using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;

namespace WindowsStartupTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            checkBoxShortcut.Checked = File.Exists(linkPath());
        }
        private string linkPath()
        {
            return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), Application.ProductName + @".lnk");
        }
        private void checkBoxShortcut_Click(object sender, EventArgs e)
        {
            string path = linkPath();

            if (checkBoxShortcut.Checked)
            {
                if (!File.Exists(path))
                {
                    IShellLink link = (IShellLink)new ShellLink();
                    link.SetDescription(Application.ProductName);
                    link.SetPath(Application.ExecutablePath);
                    link.SetIconLocation(Application.ExecutablePath, 0);
                    IPersistFile file = (IPersistFile)link;
                    file.Save(path, false);
                }
            } else
            {
                if (File.Exists(path))
                {
                    File.Delete(path);
                }
            }
        }
        #region ComImport
        [ComImport]
        [Guid("00021401-0000-0000-C000-000000000046")]
        internal class ShellLink
        {
        }
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("000214F9-0000-0000-C000-000000000046")]
        internal interface IShellLink
        {
            void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags);
            void GetIDList(out IntPtr ppidl);
            void SetIDList(IntPtr pidl);
            void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
            void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
            void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
            void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
            void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
            void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
            void GetHotkey(out short pwHotkey);
            void SetHotkey(short wHotkey);
            void GetShowCmd(out int piShowCmd);
            void SetShowCmd(int iShowCmd);
            void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
            void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
            void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
            void Resolve(IntPtr hwnd, int fFlags);
            void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
        }
        #endregion
    }
}

If you have another solution to achieve similar results, let me know in the comments 😉

Leave a Reply

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