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

Posted

技术标签:

【中文标题】如何在 Windows 启动时运行 C# 应用程序?【英文标题】:How to run a C# application at Windows startup? 【发布时间】:2011-07-02 15:42:53 【问题描述】:

我制作了一个在启动期间启动的应用程序,下面的代码如下。 重启后进程在进程管理器工具上运行,但是看不到 屏幕上的应用程序。 当我从启动注册表值打开相同的 .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 位操作系统上? 您在注册表中看到了什么? rkApp.SetValue 成功了吗? @Aliostad,我认为我们可以假设它有效,因为帖子说注册表值包含有效路径。 @bloodix,您能否从 Reg Edit 获取屏幕截图以显示您的 Run 注册表项中的内容?您的 exe 的注册表项是否与那里的其他项相似? Steve B - 我的应用程序目标是 X86,我的计算机在 32 位操作系统上运行,但具有 64 位功能。 【参考方案1】:

代码在这里(Win form 应用程序):

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);
            
        
    

【讨论】:

@BoltClock 真的很重要吗?此外,这些问题不是 WPF 问题,甚至与 WPF 有任何关系,除了提到它。即便如此,那只是无关紧要的信息。老实说,应该删除 WPF 标记,以便清除与其相关的问题详细信息。 @kelton52:同意你的最后一点。还应清理与 WinForms 有关的答案中的所有信息 - 只需查看 all 样板。 @Dinav Ahire:chkRun 是(可检查的)表单控件,它显示和控制应用程序的 start-with-windows 状态。 实际上,WPF 是相关的,因为 Application.ExecutablePath 在 WPF 应用程序中不起作用。还有其他(目前)投票率较低但答案更好的答案。【参考方案2】:

试试这个代码:

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/

【讨论】:

由于问题与 WPF 相关,请注意 Application.ExecutablePathSystem.Windows.Forms 的一部分,并将导致 WPF 项目中的 cannot resolve symbol。您可以使用System.Reflection.Assembly.GetExecutingAssembly().Location 作为适当的替代品。 Assembly.GetExecutingAssembly() 将获取当前运行代码的程序集。如果代码在另一个程序集上执行,它将无法获得正确的程序集。请改用 Assembly.GetEntryAssembly()。 链接已失效。【参考方案3】:

您可以尝试将应用程序的快捷方式复制到启动文件夹中,而不是将内容添加到注册表中。您可以使用Environment.SpecialFolder.Startup 获取路径。自 1.1 起,所有 .net 框架都提供此功能。

或者,this site 可能会对您有所帮助,它列出了许多不同的方法,您可以让应用程序自动启动。

【讨论】:

【参考方案4】:
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;
    

你可以检查整个article here

【讨论】:

虽然这在理论上可以回答这个问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。 +1 包括使用“Registry.LocalMachine.OpenSubKey”为所有用户添加/删除密钥的部分。【参考方案5】:

非常简单

在代码中添加两部分:

1- 添加命名空间

using Microsoft.Win32;

2-添加应用程序到注册表:

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

如果您想从注册表中删除应用

key.DeleteValue("your_app_name",false);

【讨论】:

【参考方案6】:

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

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

然后,我用 LocalMachine 更改了 CurrentUser,它可以工作了

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

【讨论】:

Application.ExecutablePath 返回一个字符串,我们不再需要 ToString()【参考方案7】:

我没有发现任何上述代码有效。也许那是因为我的应用程序运行的是 .NET 3.5。我不知道。以下代码对我来说非常有效。我从团队中的高级 .NET 应用程序开发人员那里得到了这个。

写(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;
    

【讨论】:

我总是遇到权限问题【参考方案8】:

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

http://startupcreator.codeplex.com/

【讨论】:

【参考方案9】:

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

this.Topmost 只是为了让我的应用位于其他窗口的顶部,您还需要添加一条 using 语句“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";
            
        

    

【讨论】:

【参考方案10】:

如果您无法设置应用程序自动启动,您可以尝试将此代码粘贴到清单

<requestedExecutionLevel  level="asInvoker" uiAccess="false" />

或删除我在应用程序中找到的清单

【讨论】:

【参考方案11】:

好的,这是我的 2 美分:尝试将每个反斜杠作为双反斜杠传递路径。我发现有时调用 WIN API 需要这样做。

【讨论】:

-1 因为它不是 WIN API 要求的,它是 C# 和 C++ 等语言解释字符串中的反斜杠字符的方式。 你会惊讶我的朋友,有时他们也需要它。当我找到示例时,我会发布 - 这是前一段时间。【参考方案12】:

我认为有一个特定的 Win32 API 调用,它采用应用程序路径并将其自动放入注册表中的适当位置,我过去曾使用过它,但我不记得函数名称了。

【讨论】:

以上是关于如何在 Windows 启动时运行 C# 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

限制 C# 和 Windows 中评估软件的启动或运行时间

如何使用c#和windows服务创建无敌的windows应用程序

C#开发Windows服务

将 C# 控制台应用程序作为 Windows 服务运行

C# / C++ 应用程序在从 Windows 运行时崩溃,而不是从 Visual Studio 运行

如何验证 Windows 服务是不是正在运行