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.
我的应用程序将有一台每台机器(不是每个用户)启动快捷方式。我可以在安装过程中创建快捷方式没问题。当用户稍后删除它然后尝试重新启用时,我的问题就来了。换句话说,他们会关闭RunOnStartup(删除Startup墨水),稍后他们会决定是否希望它在启动时运行,以便返回首选项并重新启用。
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.
显然,这是一个非常普遍的抱怨.NET,没有一种本地方法来创建快捷方式。但是,还没有找到一个很好的解决方案。
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.
而不是创建一个快捷方式。只需复制一份。这可能是一个很好的解决方案。我不能依赖于有一个开始菜单链接。但是,我想我可以创建一个并将其保存在程序目录中......这会将问题转移到我的安装程序,以便必须使用在安装时指定的相应路径创建快捷方式。
-
Do what this other * 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.
执行此其他*的答案并使用COM包装器对象。我想避免COM。它也写于2003年。所以,我不确定它将如何支持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.
此外,我必须处理普通用户(而不是管理员)尝试更改此首选项的情况。在这种情况下,我需要优雅地失败,或者在vista的情况下允许用户输入管理员密码以获得管理员安全令牌。已经适当考虑这个案例的答案将是非常棒的。
I apologize if this topic has already been covered. I searched around before posting.
如果已经涵盖了这个主题,我道歉。我在发帖前四处搜寻。
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 * question for this topic: How can I copy a file as a "Standard User" in Vista (ie "An Administrative Choice Application") by prompting user for admin credentials?
更新:复制安装程序创建的快捷方式是最佳解决方案。我将发布代码一旦完成...遇到一些障碍与a)Environment.GetSpecialFolder没有引用已解决的StartMenu ...但是,现在我正在处理提升权限将文件复制到适当的位置。我为此主题创建了一个新的*问题:如何通过提示用户输入管理员凭据,将文件复制为Vista中的“标准用户”(即“管理选择应用程序”)?
4 个解决方案
#1
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.
正如Joel所建议的那样,正确的解决方案是在安装时在程序文件文件夹中安装快捷方式,然后将.lnk复制到启动文件夹。尝试创建快捷方式更加困难。
The code below does the following:
以下代码执行以下操作:
- It gets the path to the All Users Startup Folder for you. Environment.GetSpecialFolder is fairly limited and doesn't have a reference to this folder and as a result you need to make a system call.
- Has methods to copy and remove a shortcut.
它为您获取所有用户启动文件夹的路径。 Environment.GetSpecialFolder相当有限,没有对此文件夹的引用,因此您需要进行系统调用。
有方法来复制和删除快捷方式。
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. How can I copy a file as a "Standard User" in Vista (ie "An Administrative Choice Application") by prompting user for admin credentials?
最终,我还想确保在vista上优雅地处理它,如果运行应用程序的用户是普通用户,则会提示他们输入他们的凭据。我在这里创建了一篇关于这个主题的帖子,所以如果这对你很重要,请在这里查看。如何通过提示用户输入管理员凭据,将文件复制为Vista中的“标准用户”(即“管理选择应用程序”)?
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
}
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.
在我编写此解决方案时,我想到了一种更好的处理问题的方法,该方法不需要用户升级权限以禁用启动时运行。我的解决方案是在程序加载时检查一个名为RunOnStartup的用户范围设置。要在系统加载或登录时检测应用程序是否正在启动,我在快捷方式中添加了一个参数,该参数将添加到名为shortcut的All Users - > Startup文件夹中。
// 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();
}
}
#2
You can install a shortcut to your app in it's program files folder, and then just copy that .lnk file as needed.
您可以在其程序文件文件夹中安装应用程序的快捷方式,然后根据需要复制该.lnk文件。
#3
i got it done with this
我完成了这件事
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Shell32;
using IWshRuntimeLibrary;
using System.IO;
namespace CMS.data
{
public class overall
{
public static void place_shortcut_on_desktop()
{
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\YourName.lnk";
string shortcutto = System.Reflection.Assembly.GetExecutingAssembly().Location;
var wsh = new IWshShell_Class();
IWshRuntimeLibrary.IWshShortcut shortcut = wsh.CreateShortcut(desktopPath) as IWshRuntimeLibrary.IWshShortcut;
shortcut.TargetPath = shortcutto;
shortcut.WorkingDirectory = Directory.GetParent(shortcutto).FullName;
shortcut.Save();
}
}//class overall
}
Remember the "Working Directory" it might make problems otherwise
记住它可能会产生问题的“工作目录”
you could also add the icon this way but in my case i didn't need it
你也可以这样添加图标但在我的情况下我不需要它
its my first answer here at stack overflow so a thanks would really help
这是我在堆栈溢出时的第一个答案,所以谢谢你真的会有所帮助
#4
I've been using this solution for a while now and seems to work nicely.
我一直在使用这个解决方案一段时间,似乎工作得很好。
#1
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.
正如Joel所建议的那样,正确的解决方案是在安装时在程序文件文件夹中安装快捷方式,然后将.lnk复制到启动文件夹。尝试创建快捷方式更加困难。
The code below does the following:
以下代码执行以下操作:
- It gets the path to the All Users Startup Folder for you. Environment.GetSpecialFolder is fairly limited and doesn't have a reference to this folder and as a result you need to make a system call.
- Has methods to copy and remove a shortcut.
它为您获取所有用户启动文件夹的路径。 Environment.GetSpecialFolder相当有限,没有对此文件夹的引用,因此您需要进行系统调用。
有方法来复制和删除快捷方式。
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. How can I copy a file as a "Standard User" in Vista (ie "An Administrative Choice Application") by prompting user for admin credentials?
最终,我还想确保在vista上优雅地处理它,如果运行应用程序的用户是普通用户,则会提示他们输入他们的凭据。我在这里创建了一篇关于这个主题的帖子,所以如果这对你很重要,请在这里查看。如何通过提示用户输入管理员凭据,将文件复制为Vista中的“标准用户”(即“管理选择应用程序”)?
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
}
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.
在我编写此解决方案时,我想到了一种更好的处理问题的方法,该方法不需要用户升级权限以禁用启动时运行。我的解决方案是在程序加载时检查一个名为RunOnStartup的用户范围设置。要在系统加载或登录时检测应用程序是否正在启动,我在快捷方式中添加了一个参数,该参数将添加到名为shortcut的All Users - > Startup文件夹中。
// 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();
}
}
#2
You can install a shortcut to your app in it's program files folder, and then just copy that .lnk file as needed.
您可以在其程序文件文件夹中安装应用程序的快捷方式,然后根据需要复制该.lnk文件。
#3
i got it done with this
我完成了这件事
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Shell32;
using IWshRuntimeLibrary;
using System.IO;
namespace CMS.data
{
public class overall
{
public static void place_shortcut_on_desktop()
{
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\YourName.lnk";
string shortcutto = System.Reflection.Assembly.GetExecutingAssembly().Location;
var wsh = new IWshShell_Class();
IWshRuntimeLibrary.IWshShortcut shortcut = wsh.CreateShortcut(desktopPath) as IWshRuntimeLibrary.IWshShortcut;
shortcut.TargetPath = shortcutto;
shortcut.WorkingDirectory = Directory.GetParent(shortcutto).FullName;
shortcut.Save();
}
}//class overall
}
Remember the "Working Directory" it might make problems otherwise
记住它可能会产生问题的“工作目录”
you could also add the icon this way but in my case i didn't need it
你也可以这样添加图标但在我的情况下我不需要它
its my first answer here at stack overflow so a thanks would really help
这是我在堆栈溢出时的第一个答案,所以谢谢你真的会有所帮助
#4
I've been using this solution for a while now and seems to work nicely.
我一直在使用这个解决方案一段时间,似乎工作得很好。