visual studio instalador form ejecutable datos crear como c#

c# - studio - Crear un acceso directo en el escritorio



crear instalador visual studio 2017 (11)

Quiero crear un acceso directo que apunte a algún archivo EXE, en el escritorio, usando .NET Framework 3.5 y confiando en una API oficial de Windows. ¿Cómo puedo hacer eso?


¡Usa ShellLink.cs en vbAccelerator para crear tu acceso directo fácilmente!

private static void AddShortCut() { using (ShellLink shortcut = new ShellLink()) { shortcut.Target = Application.ExecutablePath; shortcut.WorkingDirectory = Path.GetDirectoryName(Application.ExecutablePath); shortcut.Description = "My Shorcut"; shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal; shortcut.Save(SHORTCUT_FILEPATH); } }


Aquí está mi código:

public static class ShortcutHelper { #region Constants /// <summary> /// Default shortcut extension /// </summary> public const string DEFAULT_SHORTCUT_EXTENSION = ".lnk"; private const string WSCRIPT_SHELL_NAME = "WScript.Shell"; #endregion /// <summary> /// Create shortcut in current path. /// </summary> /// <param name="linkFileName">shortcut name(include .lnk extension.)</param> /// <param name="targetPath">target path</param> /// <param name="workingDirectory">working path</param> /// <param name="arguments">arguments</param> /// <param name="hotkey">hot key(ex: Ctrl+Shift+Alt+A)</param> /// <param name="shortcutWindowStyle">window style</param> /// <param name="description">shortcut description</param> /// <param name="iconNumber">icon index(start of 0)</param> /// <returns>shortcut file path.</returns> /// <exception cref="System.IO.FileNotFoundException"></exception> public static string CreateShortcut( string linkFileName, string targetPath, string workingDirectory = "", string arguments = "", string hotkey = "", ShortcutWindowStyles shortcutWindowStyle = ShortcutWindowStyles.WshNormalFocus, string description = "", int iconNumber = 0) { if (linkFileName.Contains(DEFAULT_SHORTCUT_EXTENSION) == false) { linkFileName = string.Format("{0}{1}", linkFileName, DEFAULT_SHORTCUT_EXTENSION); } if (File.Exists(targetPath) == false) { throw new FileNotFoundException(targetPath); } if (workingDirectory == string.Empty) { workingDirectory = Path.GetDirectoryName(targetPath); } string iconLocation = string.Format("{0},{1}", targetPath, iconNumber); if (Environment.Version.Major >= 4) { Type shellType = Type.GetTypeFromProgID(WSCRIPT_SHELL_NAME); dynamic shell = Activator.CreateInstance(shellType); dynamic shortcut = shell.CreateShortcut(linkFileName); shortcut.TargetPath = targetPath; shortcut.WorkingDirectory = workingDirectory; shortcut.Arguments = arguments; shortcut.Hotkey = hotkey; shortcut.WindowStyle = shortcutWindowStyle; shortcut.Description = description; shortcut.IconLocation = iconLocation; shortcut.Save(); } else { Type shellType = Type.GetTypeFromProgID(WSCRIPT_SHELL_NAME); object shell = Activator.CreateInstance(shellType); object shortcut = shellType.InvokeMethod("CreateShortcut", shell, linkFileName); Type shortcutType = shortcut.GetType(); shortcutType.InvokeSetMember("TargetPath", shortcut, targetPath); shortcutType.InvokeSetMember("WorkingDirectory", shortcut, workingDirectory); shortcutType.InvokeSetMember("Arguments", shortcut, arguments); shortcutType.InvokeSetMember("Hotkey", shortcut, hotkey); shortcutType.InvokeSetMember("WindowStyle", shortcut, shortcutWindowStyle); shortcutType.InvokeSetMember("Description", shortcut, description); shortcutType.InvokeSetMember("IconLocation", shortcut, iconLocation); shortcutType.InvokeMethod("Save", shortcut); } return Path.Combine(System.Windows.Forms.Application.StartupPath, linkFileName); } private static object InvokeSetMember(this Type type, string methodName, object targetInstance, params object[] arguments) { return type.InvokeMember( methodName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty, null, targetInstance, arguments); } private static object InvokeMethod(this Type type, string methodName, object targetInstance, params object[] arguments) { return type.InvokeMember( methodName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, targetInstance, arguments); } /// <summary> /// windows styles /// </summary> public enum ShortcutWindowStyles { /// <summary> /// Hide /// </summary> WshHide = 0, /// <summary> /// NormalFocus /// </summary> WshNormalFocus = 1, /// <summary> /// MinimizedFocus /// </summary> WshMinimizedFocus = 2, /// <summary> /// MaximizedFocus /// </summary> WshMaximizedFocus = 3, /// <summary> /// NormalNoFocus /// </summary> WshNormalNoFocus = 4, /// <summary> /// MinimizedNoFocus /// </summary> WshMinimizedNoFocus = 6, } }


Aquí hay un Método de extensión (probado), con comentarios para ayudarlo.

using IWshRuntimeLibrary; using System; namespace Extensions { public static class XShortCut { /// <summary> /// Creates a shortcut in the startup folder from a exe as found in the current directory. /// </summary> /// <param name="exeName">The exe name e.g. test.exe as found in the current directory</param> /// <param name="startIn">The shortcut''s "Start In" folder</param> /// <param name="description">The shortcut''s description</param> /// <returns>The folder path where created</returns> public static string CreateShortCutInStartUpFolder(string exeName, string startIn, string description) { var startupFolderPath = Environment.SpecialFolder.Startup.GetFolderPath(); var linkPath = startupFolderPath + @"/" + exeName + "-Shortcut.lnk"; var targetPath = Environment.CurrentDirectory + @"/" + exeName; XFile.Delete(linkPath); Create(linkPath, targetPath, startIn, description); return startupFolderPath; } /// <summary> /// Create a shortcut /// </summary> /// <param name="fullPathToLink">the full path to the shortcut to be created</param> /// <param name="fullPathToTargetExe">the full path to the exe to ''really execute''</param> /// <param name="startIn">Start in this folder</param> /// <param name="description">Description for the link</param> public static void Create(string fullPathToLink, string fullPathToTargetExe, string startIn, string description) { var shell = new WshShell(); var link = (IWshShortcut)shell.CreateShortcut(fullPathToLink); link.IconLocation = fullPathToTargetExe; link.TargetPath = fullPathToTargetExe; link.Description = description; link.WorkingDirectory = startIn; link.Save(); } } }

Y un ejemplo de uso:

XShortCut.CreateShortCutInStartUpFolder(THEEXENAME, Environment.CurrentDirectory, "Starts some executable in the current directory of application");

1st parm establece el nombre del exe (se encuentra en el directorio actual) 2nd parm es la carpeta "Start In" y 3rd parm es la descripción del atajo.

La convención de nomenclatura del enlace no deja ambigüedad en cuanto a lo que hará. Para probar el enlace simplemente haga doble clic en él.

Nota final: la aplicación en sí (objetivo) debe tener una imagen ICON asociada a ella. El enlace puede ubicar fácilmente el ICONO dentro del exe. Si la aplicación de destino tiene más de un ícono, puede abrir las propiedades del vínculo y cambiar el ícono a cualquier otro que se encuentre en el archivo ejecutable.


Aquí hay un fragmento de código que no tiene dependencia de un objeto COM externo (WSH) y admite programas de 32 bits y de 64 bits:

using System; using System.IO; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; namespace TestShortcut { class Program { static void Main(string[] args) { IShellLink link = (IShellLink)new ShellLink(); // setup shortcut information link.SetDescription("My Description"); link.SetPath(@"c:/MyPath/MyProgram.exe"); // save it IPersistFile file = (IPersistFile)link; string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); file.Save(Path.Combine(desktopPath, "MyLink.lnk"), false); } } [ComImport] [Guid("00021401-0000-0000-C000-000000000046")] internal class ShellLink { } [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("000214F9-0000-0000-C000-000000000046")] internal interface IShellLink { void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags); void GetIDList(out IntPtr ppidl); void SetIDList(IntPtr pidl); void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); void GetHotkey(out short pwHotkey); void SetHotkey(short wHotkey); void GetShowCmd(out int piShowCmd); void SetShowCmd(int iShowCmd); void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon); void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved); void Resolve(IntPtr hwnd, int fFlags); void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); } }


Con opciones adicionales como teclas rápidas, descripción, etc.

Al principio, Proyecto > Agregar referencia > COM > Windows Script Host Object Model.

using IWshRuntimeLibrary; private void CreateShortcut() { object shDesktop = (object)"Desktop"; WshShell shell = new WshShell(); string shortcutAddress = (string)shell.SpecialFolders.Item(ref shDesktop) + @"/Notepad.lnk"; IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutAddress); shortcut.Description = "New shortcut for a Notepad"; shortcut.Hotkey = "Ctrl+Shift+N"; shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolders.System) + @"/notepad.exe"; shortcut.Save(); }


Puede usar esta clase ShellLink.cs para crear el acceso directo.

Para obtener el directorio de escritorio, use:

var dir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

o use Environment.SpecialFolder.CommonDesktopDirectory para crearlo para todos los usuarios.


Sin referencia adicional:

using System; using System.Runtime.InteropServices; public class Shortcut { private static Type m_type = Type.GetTypeFromProgID("WScript.Shell"); private static object m_shell = Activator.CreateInstance(m_type); [ComImport, TypeLibType((short)0x1040), Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")] private interface IWshShortcut { [DispId(0)] string FullName { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0)] get; } [DispId(0x3e8)] string Arguments { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] set; } [DispId(0x3e9)] string Description { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] set; } [DispId(0x3ea)] string Hotkey { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] set; } [DispId(0x3eb)] string IconLocation { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] set; } [DispId(0x3ec)] string RelativePath { [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ec)] set; } [DispId(0x3ed)] string TargetPath { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] set; } [DispId(0x3ee)] int WindowStyle { [DispId(0x3ee)] get; [param: In] [DispId(0x3ee)] set; } [DispId(0x3ef)] string WorkingDirectory { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] set; } [TypeLibFunc((short)0x40), DispId(0x7d0)] void Load([In, MarshalAs(UnmanagedType.BStr)] string PathLink); [DispId(0x7d1)] void Save(); } public static void Create(string fileName, string targetPath, string arguments, string workingDirectory, string description, string hotkey, string iconPath) { IWshShortcut shortcut = (IWshShortcut)m_type.InvokeMember("CreateShortcut", System.Reflection.BindingFlags.InvokeMethod, null, m_shell, new object[] { fileName }); shortcut.Description = description; shortcut.Hotkey = hotkey; shortcut.TargetPath = targetPath; shortcut.WorkingDirectory = workingDirectory; shortcut.Arguments = arguments; if (!string.IsNullOrEmpty(iconPath)) shortcut.IconLocation = iconPath; shortcut.Save(); } }

Para crear acceso directo en el escritorio:

string lnkFileName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Notepad.lnk"); Shortcut.Create(lnkFileName, System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "notepad.exe"), null, null, "Open Notepad", "Ctrl+Shift+N", null);


Uso simplemente para mi aplicación:

using IWshRuntimeLibrary; // > Ref > COM > Windows Script Host Object ... private static void CreateShortcut() { string link = Environment.GetFolderPath( Environment.SpecialFolder.Desktop ) + Path.DirectorySeparatorChar + Application.ProductName + ".lnk"; var shell = new WshShell(); var shortcut = shell.CreateShortcut( link ) as IWshShortcut; shortcut.TargetPath = Application.ExecutablePath; shortcut.WorkingDirectory = Application.StartupPath; //shortcut... shortcut.Save(); }


Utilizo la referencia "Modelo de objetos de Windows Script Host" para crear un acceso directo.

y para crear un acceso directo en una ubicación específica:

void CreateShortcut(string linkPath, string filename) { // Create shortcut dir if not exists if (!Directory.Exists(linkPath)) Directory.CreateDirectory(linkPath); // shortcut file name string linkName = Path.ChangeExtension(Path.GetFileName(filename), ".lnk"); // COM object instance/props IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell(); IWshRuntimeLibrary.IWshShortcut sc = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(linkName); sc.Description = "some desc"; //shortcut.IconLocation = @"C:/..."; sc.TargetPath = linkPath; // save shortcut to target sc.Save(); }


EDITAR: Ya no recomiendo esta solución. Si todavía no hay un método mejor que utilizar el motor de secuencias de comandos de Windows, al menos use la solución de @Mehmet que llama al motor directamente en lugar de crear un script de texto sin formato en la memoria.

Usamos VBScript para generar un acceso directo. No necesita p / Invoke, COM Interop y DLL adicionales. Funciona así:

  • Genere un VBScript en tiempo de ejecución con los parámetros especificados del método CreateShortcut C #
  • Guarde este VBScript en un archivo temporal
  • Espera a que el script termine
  • Eliminar el archivo temporal

Aqui tienes:

static string _scriptTempFilename; /// <summary> /// Creates a shortcut at the specified path with the given target and /// arguments. /// </summary> /// <param name="path">The path where the shortcut will be created. This should /// be a file with the LNK extension.</param> /// <param name="target">The target of the shortcut, e.g. the program or file /// or folder which will be opened.</param> /// <param name="arguments">The additional command line arguments passed to the /// target.</param> public static void CreateShortcut(string path, string target, string arguments) { // Check if link path ends with LNK or URL string extension = Path.GetExtension(path).ToUpper(); if (extension != ".LNK" && extension != ".URL") { throw new ArgumentException("The path of the shortcut must have the extension .lnk or .url."); } // Get temporary file name with correct extension _scriptTempFilename = Path.GetTempFileName(); File.Move(_scriptTempFilename, _scriptTempFilename += ".vbs"); // Generate script and write it in the temporary file File.WriteAllText(_scriptTempFilename, String.Format(@"Dim WSHShell Set WSHShell = WScript.CreateObject({0}WScript.Shell{0}) Dim Shortcut Set Shortcut = WSHShell.CreateShortcut({0}{1}{0}) Shortcut.TargetPath = {0}{2}{0} Shortcut.WorkingDirectory = {0}{3}{0} Shortcut.Arguments = {0}{4}{0} Shortcut.Save", "/"", path, target, Path.GetDirectoryName(target), arguments), Encoding.Unicode); // Run the script and delete it after it has finished Process process = new Process(); process.StartInfo.FileName = _scriptTempFilename; process.Start(); process.WaitForExit(); File.Delete(_scriptTempFilename); }


acceso directo url

private void urlShortcutToDesktop(string linkName, string linkUrl) { string deskDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); using (StreamWriter writer = new StreamWriter(deskDir + "//" + linkName + ".url")) { writer.WriteLine("[InternetShortcut]"); writer.WriteLine("URL=" + linkUrl); writer.Flush(); } }

Acceso directo a la aplicación

private void appShortcutToDesktop(string linkName) { string deskDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); using (StreamWriter writer = new StreamWriter(deskDir + "//" + linkName + ".url")) { string app = System.Reflection.Assembly.GetExecutingAssembly().Location; writer.WriteLine("[InternetShortcut]"); writer.WriteLine("URL=file:///" + app); writer.WriteLine("IconIndex=0"); string icon = app.Replace(''//', ''/''); writer.WriteLine("IconFile=" + icon); writer.Flush(); } }

también revisa estos

ejemplo 1 example2

si desea utilizar algunas funciones específicas de la API, querrá utilizar la IShellLink interface y la IPersistFile interface (a través de la interoperabilidad COM).

example2