如何创建为我的应用程序启动文件夹中编程的.NET / C#添加一个快捷方式(.lnk) [英] How do I create add a shortcut (.lnk) for my application to the Startup folder programatically in .NET/C#

查看:148
本文介绍了如何创建为我的应用程序启动文件夹中编程的.NET / C#添加一个快捷方式(.lnk)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序将有每台机器(而不是每用户)启动快捷方式。我可以创建在安装过程中没有问题的捷径。我的问题是当用户以后删除它,然后尝试重新启用。在otherwords,他们关闭RunOnStartup(这将删除启动油墨),并在他们决定他们想要它在启动时运行,使他们重新回到喜好和以后的时间重新启用。

My application will have a per machine (not per user) Startup shortcut. I can create a shortcut during the installer process no problem. My problem comes when the user later removes it and then tries to re-enable. In otherwords, they turn off RunOnStartup (which deletes the Startup ink) and at a later time they decide they do want it to run on startup so they go back into preferences and re-enable.

显然,这是使用.NET一个很常见的抱怨是没有创建快捷方式本机的方式。但是,还没有找到一个很好的解决方案。

Apparently, this is a pretty common gripe with .NET that there isn't a native way to create shortcuts. But, haven't found a very good solution.

我已经找到解决方案/考虑:

Solutions I've Found/Considered:


  • 相反然后创建一个快捷方式。仅复制。这可能是一个很好的解决方案。我不能依靠那里是一个开始菜单链接。但是,我想我大概可以创建一个并保存在程序目录...这个交给我的安装人员必须与这会在安装时指定适当的路径创建快捷方式转变的问题。

  • Rather then create a shortcut. Just copy one. This might be a good solution. I can't depend on there being a Start Menu link. But, I guess I could probably create one and keep it in Program Directory... This shifts the problem over to my installer to have to create the shortcut with the appropriate path which would be specified at install time.

做什么的这个计算器其他答案是和使用COM包装对象。我想避免COM。也有人写于2003年。所以,我不知道它会如何很好地支持Vista。我给它一个镜头,但没有一个远景盒旁边。

Do what this other stackoverflow answer is and use a COM wrapper object. I'd like to avoid COM. It was also written in 2003. So, I'm not sure how well it's going to support vista. I'd give it a shot but don't have a vista box handy.

使用注册表来代替。这是我目前是怎么做的......但碰上在Vista上的问题。看来,启动菜单快捷方式来做到这一点所以这是我的目标是什么的正确方法的普遍共识。

Use the registry instead. This is how I currently do it... but run into issues on Vista. It seems the general consensus that Startup Menu shortcuts are the proper way to do this so that's what my goal is.

此外,我必须处理一个普通用户(不是管理员)试图改变这种偏好的情况。在这种情况下,我需要正常失败,或在vista中的情况下,允许用户输入管理员密码获得管理员安全令牌。这已经适当考虑到考虑这种情况下,答案将是真棒。

Also, I have to handle the case that a regular user (not an admin) tries to change this preference. In this case, I need to gracefully fail or in the case of vista allow the user to enter the Admin password to get a Admin security token. An answer which already properly takes into consider this case would be awesome.

我道歉,如果这个话题已经被覆盖。我四处寻找,然后再发布。

I apologize if this topic has already been covered. I searched around before posting.

更新:复制快捷方式这创造您的安装程序是最好的解决方案。我会后的代码一次吃完...跑进一些障碍与一)Environment.GetSpecialFolder不必已解决的StartMenu参考...但是,现在我正在处理提升权限的文件复制到适当的位置。我创建了这个主题一个新的计算器问题:的 http://stackoverflow.com/questions/1039875/how-can-i-copy-a-file-as-a-standard-user-in-vista-ie-an-行政选择题

UPDATE: Copying a shortcut which your installer created is the best solution. I'll post code once finished... ran into some hurdles with a) Environment.GetSpecialFolder not having a reference to the StartMenu which has been resolved... But, now i'm dealing with elevating permissions to copy the file to the proper location. I created a new stackoverflow question for this topic: http://stackoverflow.com/questions/1039875/how-can-i-copy-a-file-as-a-standard-user-in-vista-ie-an-administrative-choice

推荐答案

的建议由Joel,正确的解决办法是在Program Files文件夹中安装快捷方式在安装时,然后.LNK复制到启动文件夹。试图创建一个快捷方式是比较困难的。

As suggested by Joel, the proper solution is to install a shortcut in your program files folder at install time and then copy the .lnk to the startup folder. Trying to create a shortcut is more difficult.

下面的代码执行以下操作:

The code below does the following:


  • 它到达的路径所有用户启动文件夹为您服务。 Environment.GetSpecialFolder是相当有限的,没有这个文件夹的引用,因此需要进行系统调用。

  • 的方法,以复制和删除快捷方式。

最后,我想也使确保它已被适当地在Vista上如果处理运行应用程序的用户是他们将被提示输入凭据普通用户。我创建了一个帖子在这里关于这个问题,以便检查到这里,如果这对你很重要。
http://stackoverflow.com/questions/1039875/how-can-i-copy-a-file-as-a-standard-user-in-vista-ie-an-administrative-choice

Ultimately, I wanted to also make sure that it was gracefully handled on vista if the user running the application was a regular user they would be prompted to enter their credentials. I created a post here on the subject so check into that here if that's important to you. http://stackoverflow.com/questions/1039875/how-can-i-copy-a-file-as-a-standard-user-in-vista-ie-an-administrative-choice

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Principal;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace BR.Util
{
public class StartupLinkUtil
{
    [DllImport("shell32.dll")]
    static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder, bool fCreate);

    public static string getAllUsersStartupFolder()
    {
        StringBuilder path = new StringBuilder(200);
        SHGetSpecialFolderPath(IntPtr.Zero, path, CSIDL_COMMON_STARTUP, false);
        return path.ToString();
    }


    private static string getStartupShortcutFilename()
    {
        return Path.Combine(getAllUsersStartupFolder(), Application.ProductName) + ".lnk";
    }

   public static bool CopyShortcutToAllUsersStartupFolder(string pShortcutName)
    {
        bool retVal = false;
        FileInfo shortcutFile = new FileInfo(pShortcutName);
        FileInfo destination = new FileInfo(getStartupShortcutFilename());

        if (destination.Exists)
        {
            // Don't do anything file already exists.  -- Potentially overwrite?
        }
        else if (!shortcutFile.Exists)
        {
            MessageBox.Show("Unable to RunOnStartup because '" + pShortcutName + "' can't be found.  Was this application installed properly?");
        }
        else
        {
            retVal = copyFile(shortcutFile, destination);
        }
        return retVal;
    }

    public static bool doesShortcutExistInAllUsersStartupFolder()
    {
        return File.Exists(getStartupShortcutFilename());
    }

    public static bool RemoveShortcutFromAllUsersStartupFolder() {
        bool retVal = false;
        string path = Path.Combine(getAllUsersStartupFolder(), Application.ProductName) + ".lnk";
        if( File.Exists(path) ) {
            try
            {
                File.Delete(path);
                retVal = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Unable to remove this application from the Startup list.  Administrative privledges are required to perform this operation.\n\nDetails: SecurityException: {0}", ex.Message), "Update Startup Mode", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        return retVal;
    }

    // TODO: Test this in vista to see if it prompts for credentials.
    public static bool copyFile(FileInfo pSource, FileInfo pDestination)
    {
        bool retVal = false;

        try
        {
            File.Copy(pSource.FullName, pDestination.FullName);
            //MessageBox.Show("File has successfully been added.", "Copy File", MessageBoxButtons.OK, MessageBoxIcon.Information);
            retVal = true;
        }
        catch (System.Security.SecurityException secEx)
        {
            MessageBox.Show(string.Format("SecurityException: {0}", secEx.Message), "Copy File", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        catch (UnauthorizedAccessException authEx)
        {
            MessageBox.Show(string.Format("UnauthorizedAccessException: {0}", authEx.Message), "Copy File", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Copy File", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        return retVal;
    }

    #region Special Folder constants
    const int CSIDL_DESKTOP = 0x0000;        // <desktop>
    const int CSIDL_INTERNET = 0x0001;        // Internet Explorer (icon on desktop)
    const int CSIDL_PROGRAMS = 0x0002;        // Start Menu\Programs
    const int CSIDL_CONTROLS = 0x0003;        // My Computer\Control Panel
    const int CSIDL_PRINTERS = 0x0004;        // My Computer\Printers
    const int CSIDL_PERSONAL = 0x0005;        // My Documents
    const int CSIDL_FAVORITES = 0x0006;        // <user name>\Favorites
    const int CSIDL_STARTUP = 0x0007;        // Start Menu\Programs\Startup
    const int CSIDL_RECENT = 0x0008;        // <user name>\Recent
    const int CSIDL_SENDTO = 0x0009;        // <user name>\SendTo
    const int CSIDL_BITBUCKET = 0x000a;        // <desktop>\Recycle Bin
    const int CSIDL_STARTMENU = 0x000b;        // <user name>\Start Menu
    const int CSIDL_MYDOCUMENTS = CSIDL_PERSONAL; //  Personal was just a silly name for My Documents
    const int CSIDL_MYMUSIC = 0x000d;        // "My Music" folder
    const int CSIDL_MYVIDEO = 0x000e;        // "My Videos" folder
    const int CSIDL_DESKTOPDIRECTORY = 0x0010;        // <user name>\Desktop
    const int CSIDL_DRIVES = 0x0011;        // My Computer
    const int CSIDL_NETWORK = 0x0012;        // Network Neighborhood (My Network Places)
    const int CSIDL_NETHOOD = 0x0013;        // <user name>\nethood
    const int CSIDL_FONTS = 0x0014;        // windows\fonts
    const int CSIDL_TEMPLATES = 0x0015;
    const int CSIDL_COMMON_STARTMENU = 0x0016;        // All Users\Start Menu
    const int CSIDL_COMMON_PROGRAMS = 0x0017;        // All Users\Start Menu\Programs
    const int CSIDL_COMMON_STARTUP = 0x0018;        // All Users\Startup
    const int CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019;        // All Users\Desktop
    const int CSIDL_APPDATA = 0x001a;        // <user name>\Application Data
    const int CSIDL_PRINTHOOD = 0x001b;        // <user name>\PrintHood
    const int CSIDL_LOCAL_APPDATA = 0x001c;        // <user name>\Local Settings\Applicaiton Data (non roaming)
    const int CSIDL_ALTSTARTUP = 0x001d;        // non localized startup
    const int CSIDL_COMMON_ALTSTARTUP = 0x001e;        // non localized common startup
    const int CSIDL_COMMON_FAVORITES = 0x001f;
    const int CSIDL_INTERNET_CACHE = 0x0020;
    const int CSIDL_COOKIES = 0x0021;
    const int CSIDL_HISTORY = 0x0022;
    const int CSIDL_COMMON_APPDATA = 0x0023;        // All Users\Application Data
    const int CSIDL_WINDOWS = 0x0024;        // GetWindowsDirectory()
    const int CSIDL_SYSTEM = 0x0025;        // GetSystemDirectory()
    const int CSIDL_PROGRAM_FILES = 0x0026;        // C:\Program Files
    const int CSIDL_MYPICTURES = 0x0027;        // C:\Program Files\My Pictures
    const int CSIDL_PROFILE = 0x0028;        // USERPROFILE
    const int CSIDL_SYSTEMX86 = 0x0029;        // x86 system directory on RISC
    const int CSIDL_PROGRAM_FILESX86 = 0x002a;        // x86 C:\Program Files on RISC
    const int CSIDL_PROGRAM_FILES_COMMON = 0x002b;        // C:\Program Files\Common
    const int CSIDL_PROGRAM_FILES_COMMONX86 = 0x002c;        // x86 Program Files\Common on RISC
    const int CSIDL_COMMON_TEMPLATES = 0x002d;        // All Users\Templates
    const int CSIDL_COMMON_DOCUMENTS = 0x002e;        // All Users\Documents
    const int CSIDL_COMMON_ADMINTOOLS = 0x002f;        // All Users\Start Menu\Programs\Administrative Tools
    const int CSIDL_ADMINTOOLS = 0x0030;        // <user name>\Start Menu\Programs\Administrative Tools
    const int CSIDL_CONNECTIONS = 0x0031;        // Network and Dial-up Connections
    const int CSIDL_COMMON_MUSIC = 0x0035;        // All Users\My Music
    const int CSIDL_COMMON_PICTURES = 0x0036;        // All Users\My Pictures
    const int CSIDL_COMMON_VIDEO = 0x0037;        // All Users\My Video
    const int CSIDL_RESOURCES = 0x0038;        // Resource Direcotry
    const int CSIDL_RESOURCES_LOCALIZED = 0x0039;        // Localized Resource Direcotry
    const int CSIDL_COMMON_OEM_LINKS = 0x003a;        // Links to All Users OEM specific apps
    const int CSIDL_CDBURN_AREA = 0x003b;        // USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
    const int CSIDL_COMPUTERSNEARME = 0x003d;        // Computers Near Me (computered from Workgroup membership)
    const int CSIDL_FLAG_CREATE = 0x8000;        // combine with CSIDL_ value to force folder creation in SHGetFolderPath()
    const int CSIDL_FLAG_DONT_VERIFY = 0x4000;        // combine with CSIDL_ value to return an unverified folder path
    const int CSIDL_FLAG_DONT_UNEXPAND = 0x2000;        // combine with CSIDL_ value to avoid unexpanding environment variables
    const int CSIDL_FLAG_NO_ALIAS = 0x1000;        // combine with CSIDL_ value to insure non-alias versions of the pidl
    const int CSIDL_FLAG_PER_USER_INIT = 0x0800;        // combine with CSIDL_ value to indicate per-user init (eg. upgrade)
    #endregion
}

当我在写这个解决方案,我认为处理这不会要求用户必须升级privledges为了禁止在启动时运行的问题,更好的办法。
我的解决办法是,如果用户设定范围称为RunOnStartup加载的程序,尽快检查。为了检测是否在系统负载或日志中我添加了一个参数,它被添加到所有用户的快捷应用程序正在启动 - >启动文件夹,名为快捷方式。

While I was writing this solution, I thought of a better way of handling the problem which wouldn't require users to have escalated privledges in order to disable run on startup. My solution was to check as soon as the program loaded if a user scoped setting called RunOnStartup. To detect if the application was being started when the system loads or logs in I added an argument to the shortcut which gets added to the All Users -> Startup folder called shortcut.

        // Quit the application if the per user setting for RunOnStartup is false.
            if (args != null && args.Length > 0 && args[0].Contains("startup"))
            {
                if (Settings1.Default.RunOnStartup == false)
                {
                    Application.Exit();
                }
            }

这篇关于如何创建为我的应用程序启动文件夹中编程的.NET / C#添加一个快捷方式(.lnk)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆