如何在Windows启动时运行C#应用程序?

72

我制作了一个在启动时启动的应用程序,代码如下。
重启后,该进程会在进程管理器工具上运行,但我无法在屏幕上看到该应用程序。 当我从启动注册表值打开相同的.exe文件时,程序运行得很完美。

// The path to the key where Windows looks for startup applications
RegistryKey rkApp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);

// Add the value in the registry so that the application runs at startup
rkApp.SetValue("MyApp", Application.ExecutablePath.ToString());

我该怎么做才能修复它?


你的应用程序是否针对x86架构,而你的计算机运行在64位操作系统上? - Steve B
1
你在注册表中看到了什么?rkApp.SetValue 是否成功了? - Aliostad
@Aliostad,我认为我们可以假设它有效,因为帖子说注册表值包含有效路径。 - Phil Gan
@bloodix,你能否从Reg Edit中获取一个截图来展示你的Run注册表键中有什么?你的exe的注册表条目是否看起来与其他条目相似? - AAT
Steve B - 我的应用程序目标是X86,我的计算机运行在32位操作系统上,但具有64位能力。 - Oded .S
@Aliostad,我手动检查了同一注册表目录下的另一个.exe进程,它可以正常运行。为什么我的特定应用程序会出现问题呢? - Oded .S
12个回答

69
代码在这里(Win窗体应用程序):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;

namespace RunAtStartup
{
    public partial class frmStartup : Form
    {
        // The path to the key where Windows looks for startup applications
        RegistryKey rkApp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);

        public frmStartup()
        {
            InitializeComponent();
            // Check to see the current state (running at startup or not)
            if (rkApp.GetValue("MyApp") == null)
            {
                // The value doesn't exist, the application is not set to run at startup
                chkRun.Checked = false;
            }
            else
            {
                // The value exists, the application is set to run at startup
                chkRun.Checked = true;
            }
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            if (chkRun.Checked)
            {
                // Add the value in the registry so that the application runs at startup
                rkApp.SetValue("MyApp", Application.ExecutablePath);
            }
            else
            {
                // Remove the value from the registry so that the application doesn't start
                rkApp.DeleteValue("MyApp", false);
            }
        }
    }
}

9
@BoltClock这真的重要吗?此外,这个问题并不是一个WPF问题,或者与WPF没有任何关系,除了提到它之外。即便如此,那也只是多余的信息。说实话,WPF标签应该被删除,与之相关的问题细节也应该被清除。 - Kelly Elton
@kelton52:同意你的最后一点。此外,答案中与WinForms相关的所有信息都应该被清理干净——看看那些样板代码。 - BoltClock
3
chkRun 是一个可勾选的表单控件,用于显示和控制程序随 Windows 启动时的状态。 - Glitch
实际上,WPF很重要,因为Application.ExecutablePath在WPF应用程序中无法工作。还有其他回答得票较低但更好的答案。 - stricq
路径 SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run 非常重要。 - Muhammad Khuzaima Umair

46

试试这段代码:

private void RegisterInStartup(bool isChecked)
{
    RegistryKey registryKey = Registry.CurrentUser.OpenSubKey
            ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
    if (isChecked)
    {
        registryKey.SetValue("ApplicationName", Application.ExecutablePath);
    }
    else
    {
        registryKey.DeleteValue("ApplicationName");
    }
}

源(已失效):http://www.dotnetthoughts.net/2010/09/26/run-the-application-at-windows-startup/

存档链接:https://web.archive.org/web/20110104113608/http://www.dotnetthoughts.net/2010/09/26/run-the-application-at-windows-startup/


17
由于这个问题与WPF相关,需要注意Application.ExecutablePathSystem.Windows.Forms的一部分,在WPF项目中会导致无法解析符号的错误。您可以使用System.Reflection.Assembly.GetExecutingAssembly().Location作为适当的替代方案。 - itsho
5
Assembly.GetExecutingAssembly() 可以获取当前正在运行代码的程序集,但如果代码在另一个程序集上执行,则无法获取正确的程序集。应该使用 Assembly.GetEntryAssembly() 代替。 - SilverCorvus
链接已失效。 - Hakan Fıstık

18

您可以尝试将应用程序的快捷方式复制到启动文件夹中,而不是将其添加到注册表中。您可以使用 Environment.SpecialFolder.Startup 获取该路径。它在所有 .net 框架版本1.1及以上都可用。

或者,也许这个网站会对您有所帮助,它列出了很多不同的方法,可以让应用程序自动启动。


13
public class StartUpManager
{
    public static void AddApplicationToCurrentUserStartup()
    {
        using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
        {
            key.SetValue("My ApplicationStartUpDemo", "\"" + System.Reflection.Assembly.GetExecutingAssembly().Location + "\"");
        }
    }

    public static void AddApplicationToAllUserStartup()
    {
        using (RegistryKey key =     Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
        {
            key.SetValue("My ApplicationStartUpDemo", "\"" + System.Reflection.Assembly.GetExecutingAssembly().Location + "\"");
        }
    }

    public static void RemoveApplicationFromCurrentUserStartup()
    {
         using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
         {
             key.DeleteValue("My ApplicationStartUpDemo", false);
         }
    }

    public static void RemoveApplicationFromAllUserStartup()
    {
        using (RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
        {
            key.DeleteValue("My ApplicationStartUpDemo", false);
        }
    }

    public static bool IsUserAdministrator()
    {
        //bool value to hold our return value
        bool isAdmin;
        try
        {
            //get the currently logged in user
            WindowsIdentity user = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(user);
            isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
        }
        catch (UnauthorizedAccessException ex)
        {
            isAdmin = false;
        }
        catch (Exception ex)
        {
            isAdmin = false;
        }
        return isAdmin;
    }
}

你可以在这里查看整篇文章


虽然这理论上回答了问题,但最好在此处包含答案的关键部分,并提供参考链接。 - Kevin Brown-Silva
1
+1 如果包括使用 "Registry.LocalMachine.OpenSubKey" 添加/删除所有用户的键的部分。 - Ashish Gupta

5
它非常简单。在代码中添加两个部分:
1- 添加命名空间:
using Microsoft.Win32;

添加应用程序到注册表:
RegistryKey key=Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
key.SetValue("your_app_name", Application.ExecutablePath);

如果您想从注册表中删除应用程序:
key.DeleteValue("your_app_name",false);

1

我发现以上的代码都没有起作用。也许是因为我的应用程序是在.NET 3.5上运行。我不知道。下面的代码对我来说完美地解决了问题,我从我们团队的一位资深.NET应用程序开发人员那里得到了这段代码:

Write(Microsoft.Win32.Registry.LocalMachine, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run\", "WordWatcher", "\"" + Application.ExecutablePath.ToString() + "\"");
public bool Write(RegistryKey baseKey, string keyPath, string KeyName, object Value)
{
    try
    {
        // Setting 
        RegistryKey rk = baseKey;
        // I have to use CreateSubKey 
        // (create or open it if already exits), 
        // 'cause OpenSubKey open a subKey as read-only 
        RegistryKey sk1 = rk.CreateSubKey(keyPath);
        // Save the value 
        sk1.SetValue(KeyName.ToUpper(), Value);

        return true;
    }
    catch (Exception e)
    {
        // an error! 
        MessageBox.Show(e.Message, "Writing registry " + KeyName.ToUpper());
        return false;
    }
}

我总是遇到权限问题。 - Jamshaid K.

1

首先,我尝试了下面的代码,但它没有起作用。

RegistryKey rkApp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
rkApp.SetValue("MyAPP", Application.ExecutablePath.ToString());

然后,我将CurrentUser改为LocalMachine,它就可以工作了。

RegistryKey rkApp = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
rkApp.SetValue("MyAPP", Application.ExecutablePath.ToString());

2
Application.ExecutablePath 返回一个字符串,我们不再需要使用 ToString() 方法了 - Ahsan

0
一个名为“Startup Creator”的开源应用程序通过创建脚本并提供易于使用的界面来配置Windows启动。利用强大的VBScript,它允许应用程序或服务在定时延迟间隔内启动,始终按照相同的顺序。这些脚本会自动放置在您的启动文件夹中,并可以在将来重新打开以允许修改。

http://startupcreator.codeplex.com/


0
如果您无法设置应用程序自启动,可以尝试将此代码粘贴到清单中。
<requestedExecutionLevel  level="asInvoker" uiAccess="false" />

或者删除清单,我在我的应用程序中找到了它


0

针对 WPF:(其中 lblInfo 是标签,chkRun 是复选框)

this.Topmost 只是为了让我的应用程序保持在其他窗口的顶部,您还需要添加一个使用语句 " using Microsoft.Win32; ", StartupWithWindows 是我的应用程序名称。

public partial class MainWindow : Window
    {
        // The path to the key where Windows looks for startup applications
        RegistryKey rkApp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);

        public MainWindow()
        {
            InitializeComponent();
            if (this.IsFocused)
            {
                this.Topmost = true;
            }
            else
            {
                this.Topmost = false;
            }

            // Check to see the current state (running at startup or not)
            if (rkApp.GetValue("StartupWithWindows") == null)
            {
                // The value doesn't exist, the application is not set to run at startup, Check box
                chkRun.IsChecked = false;
                lblInfo.Content = "The application doesn't run at startup";
            }
            else
            {
                // The value exists, the application is set to run at startup
                chkRun.IsChecked = true;
                lblInfo.Content = "The application runs at startup";
            }
            //Run at startup
            //rkApp.SetValue("StartupWithWindows",System.Reflection.Assembly.GetExecutingAssembly().Location);

            // Remove the value from the registry so that the application doesn't start
            //rkApp.DeleteValue("StartupWithWindows", false);

        }

        private void btnConfirm_Click(object sender, RoutedEventArgs e)
        {
            if ((bool)chkRun.IsChecked)
            {
                // Add the value in the registry so that the application runs at startup
                rkApp.SetValue("StartupWithWindows", System.Reflection.Assembly.GetExecutingAssembly().Location);
                lblInfo.Content = "The application will run at startup";
            }
            else
            {
                // Remove the value from the registry so that the application doesn't start
                rkApp.DeleteValue("StartupWithWindows", false);
                lblInfo.Content = "The application will not run at startup";
            }
        }

    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接