2011-02-04 85 views
76

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?Crear acceso directo en el escritorio C#

+0

El uso del modelo de objetos de host de Windows Script de Rustam Irzaev es el único confiable para un acceso directo adecuado. ayush: esta técnica omite un montón de características como teclas de acceso rápido y descripciones. Thorarin: ShellLink funciona bien en la mayoría de los casos, pero notablemente no funciona en Windows XP y crea accesos directos no válidos. Simon Mourier: Esto fue muy prometedor, pero crea accesos directos no válidos en Windows 8. – BrutalDev

Respuesta

66

URL de acceso directo

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 de 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 comprobar estos

example 1 example2

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

Here is an article that goes into detail what you need to do it, as well as sample code:

+0

Estos anteriores están funcionando bien. Pero quiero crear acceso directo a través de algunas funciones de API como DllImport ("coredll.dll")] public static extern int SHCreateShortcut (StringBuilder szShortcut, StringBuilder szTarget); –

+0

@Vipin ¿por qué? ¿Hay alguna razón por la que alguna de las soluciones anteriores no sea lo suficientemente buena? – alex

+1

un usuario estúpido puede cambiarlo –

20

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

Para obtener el directorio del escritorio, utilice:

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

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

+0

¡Gracias! Está funcionando bien. –

+6

@Vipin: si una solución funciona para usted, se acostumbra recitarla. Además, debe seleccionar la mejor solución y aceptarla como la respuesta a su problema. – Thorarin

+0

ShellLink.cs no funciona en Windows XP. – BrutalDev

84

Con opciones adicionales como teclas de acceso rápido, descripción, etc.

En un primer momento, el Proyecto > Agregar referencia > COM > Windows Script Host Modelo de objetos.

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(); 
} 
+0

Esto funcionó bien para mí. – tofutim

+1

Esto fue muy cercano para mí. Necesitaba agregar el directorio .exe a la propiedad "WorkingDirectory" en el acceso directo. (shortcut.WorkingDirectory) +1 – samuelesque

+1

Para especificar un índice de ícono (en IconLocation), use un valor como "path_to_icon_file, #", donde # es el índice del ícono. Consulte https://msdn.microsoft.com/en-us/library/xsy6k3ys(v=vs.84).aspx – Chris

8

Uso ShellLink.cs en vbAccelerator para crear el 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); 
} 
} 
+1

Ese enlace ahora está muerto, pero puede encontrar una versión archivada de este [aquí] (https://web.archive.org/web/20150414052035/http://www.vbaccelerator.com/home/NET/Code/ Libraries/Shell_Projects/Creating_and_Modifying_Shortcuts/article.asp). –

10

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

Aquí es una pieza de código que no tiene dependencia de un objeto COM externo (WSH), y es compatible con los programas de 32 bits y 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); 
    } 
} 
+0

Esta técnica no funciona en Windows 8. – BrutalDev

+0

@BrutalDev - ¿Qué no funciona? Lo probé en Windows 8 x64 y funciona. –

+0

También ejecutando Win8 x64, copié el ejemplo de código anterior exactamente como está, crea un icono en mi escritorio sin ruta. La ejecución del enlace solo abre el explorador en el escritorio. Este es un problema similar que tuve con ShellLink.cs pero en Windows XP/2003. El único ejemplo que definitivamente funciona en todas las versiones de Windows fue que Rustam Irzaev usó WSHOM como mencioné en mi comentario a la pregunta principal: "Esto fue muy prometedor, pero crea accesos directos no válidos en Windows 8" – BrutalDev

5

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.

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

  • Generar un VBScript en tiempo de ejecución con los parámetros especificados del # método CreateShortcut C
  • Guardar este VBScript en un archivo temporal
  • Espere a que la secuencia de comandos para terminar
  • Eliminar el temporal archivo

Aquí van:

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

Uso la referencia "Windows Script Host Object Model" para crear acceso directo.

Adding "Windows Script Host Object Model" to project references

y crear acceso directo en la 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(); 
    } 
4

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, 
    } 
} 
8

puedo utilizar 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(); 
    } 
+0

Funciona de la caja, simplemente copia -Pasarlo – rluks

1

Su e es 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 su uso:

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

primera Parm establece el nombre exe (que se encuentra en el directorio actual) 2º Parm es el "Inicio En" carpeta y tercera Parm es la descripción de acceso directo.

Example of Using this code

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

Final Nota: la aplicación en sí (objetivo) debe tener una imagen ICONO asociada. 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.

+0

Recibo un mensaje de error que dice que .GetFolderPath() no existe. Lo mismo para XFile.Delete. ¿Qué me estoy perdiendo? – RalphF

+0

¿Ocurre un error aquí? Environment.SpecialFolder.Startup.GetFolderPath(); –

Cuestiones relacionadas