以编程方式在Run和RunOnce Registry中运行应用程序

时间:2015-04-01 15:21:57

标签: c# .net registry

我开发了一个用WPF / C#编写的自定义shell,它将explorer.exe替换为Windows 8.1系统上的shell。一切运行正常,除了我想在Run / RunOnce注册表位置运行应用程序。主要问题是似乎没有标准的方式将条目放入注册表 - 有些在条目周围有双引号,有些没有;有些是通过rundll32运行的,并且定义了一个入口点,后跟逗号分隔的参数;有些人有空格分隔的论点;有些在一个条目中有一些可执行文件 是否有我可以调用的服务或可执行文件来运行这些条目,或者我是不是试图找到一种方法来尽可能地解析它并使用Process.Start()?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我必须为工作中的项目做类似的事情。以下代码或多或少是我写的。我无法保证它是万无一失的,但它似乎与我测试的注册表一起使用。

public static class ProcessHelper
{
    const string RegistrySubKeyName =
        @"Software\Microsoft\Windows\CurrentVersion\Run";

    public static void LaunchStartupPrograms()
    {
        foreach (string commandLine in GetStartupProgramCommandLines())
        {
            string fileName;
            string arguments;

            if (File.Exists(commandLine))
            {
                fileName = commandLine;
                arguments = String.Empty;
            }
            else if (commandLine.StartsWith("\""))
            {
                int secondQuoteIndex = commandLine.IndexOf("\"", 1);
                fileName = commandLine.Substring(1, secondQuoteIndex - 1);

                if (commandLine.EndsWith("\""))
                {
                    arguments = String.Empty;
                }
                else
                {
                    arguments = commandLine.Substring(secondQuoteIndex + 2);
                }
            }
            else
            {
                int firstSpaceIndex = commandLine.IndexOf(' ');
                if (firstSpaceIndex == -1)
                {
                    fileName = commandLine;
                    arguments = String.Empty;
                }
                else
                {
                    fileName = commandLine.Substring(0, firstSpaceIndex);
                    arguments = commandLine.Substring(firstSpaceIndex + 1);
                }
            }

            Process.Start(fileName, arguments);
        }
    }

    static IEnumerable<string> GetStartupProgramCommandLines()
    {
        using (RegistryKey key =
            Registry.CurrentUser.OpenSubKey(RegistrySubKeyName))
        {
            foreach (string name in key.GetValueNames())
            {
                string commandLine = (string) key.GetValue(name);
                yield return commandLine;
            }
        }

        using (RegistryKey key =
            Registry.LocalMachine.OpenSubKey(RegistrySubKeyName))
        {
            foreach (string name in key.GetValueNames())
            {
                string commandLine = (string) key.GetValue(name);
                yield return commandLine;
            }
        }
    }
}