giovedì 30 dicembre 2010

Creare uno shortcut con VB.NET

Prendendo spunto da un post comparso sul forum MSDN vorrei proporvi un tip su come creare uno shortcut utilizzando VB.NET.

Per poter creare uno shortcut possiamo procedere in due modi: o ci studiamo la struttura del file .lnk e scriviamo una classe che è in grado di ricreare tale struttura oppure utilizziamo Windows Scripting Host.

La prima soluzione è percorribile ma laboriosa perchè la struttura di un file lnk non è banale. Chi fosse interessato a vedere come è composto, internamente, un file lnk può scaricare la seguente reference guide (link).

Io vorrei proporvi la seconda strada e realizzerò una classe che incapsula l’utilizzo di Windows Scripting Host.

L’object model di Windows Scripting Host è contenuto nella dll IWshRuntimeLibrary che può essere referenziata, nel nostro progetto, utilizzando il tab COM della finestra di aggiunta delle reference:

image

Tra gli oggetti che troviamo all’interno della libreria utilizzeremo la classe WshShell e la classe WshShortcut.

La prima delle due rappresenta la vera e propria shell di Windows Scripting Host e, tra i tanti metodi messi a disposizione, ha il metodo CreateShortcut() che prevede come argomento il nome dello shortcut completo di path ed estensione e restituisce un oggetto di classe WshShortcut o di classe WshUrlShortcut (in realtà il metodo, essendo COM, restituisce un object ma possiamo castare il risultato alla classe WshShortcut o WshUrlShortcut a nostro piacimento).

La chiamata al metodo CreateShortcut non crea fisicamente il link ma tale link è creato utilizzando l’oggetto restituito dal metodo. Per maggiori info sulla classe WshShell fare riferimento al seguente link.

L’oggetto WshShortcut rappresenta, quindi, un link (il WshUrlShortcut, di fatto, ha un sottoinsieme di proprietà del WshShortcut ed è pensato per il link web) e mette a disposizione tutte quelle proprietà che ci servono per definire il link stesso (ad esempio l’icona, la directory di lavoro, la descrizione, etc., etc.). Per maggiori info sulla classe WshShortcut fare riferimento al seguente link.

La classe che vogliamo realizzare prevede una serie di proprietà per la definizione dello shortcut e un metodo per il salvataggio dello stesso (in maniera del tutto analoga a quanto fa la WshShortcut) e incapsulerà l’utilizzo delle due precedenti classi di scripting.

  1. Imports IWshRuntimeLibrary
  2.  
  3. Public Class Shortcut
  4.  
  5.     Public Sub New(ByVal shortcutFullName As String)
  6.         Me.ShortcutFullName = shortcutFullName
  7.     End Sub
  8.  
  9.     Private _ShortcutFullName As String
  10.     Public Property ShortcutFullName As String
  11.         Get
  12.             Return _ShortcutFullName
  13.         End Get
  14.         Set(ByVal value As String)
  15.             If String.IsNullOrWhiteSpace(value) Then Throw New ArgumentNullException("ShortcutFullName", "ShortcutFullName non può essere vuoto!")
  16.             _ShortcutFullName = value
  17.         End Set
  18.     End Property
  19.  
  20.     Public Property TargetPath As String
  21.     Public Property WindowStyle As ShortcutWindowsStyle = ShortcutWindowsStyle.NormalFocus
  22.     Public Property Hotkey As String
  23.     Public Property IconPath As String
  24.     Public Property IconIndex As Int16 = 0
  25.     Public Property Description As String
  26.     Public Property WorkingDirectory As String
  27.     Public Property Arguments As String
  28.  
  29.     Public Function Save() As Boolean
  30.         Dim retval = False
  31.         Dim shortCut As IWshShortcut = Nothing
  32.         Dim shell As WshShell = Nothing
  33.         Try
  34.             shell = New WshShell()
  35.         Catch ex As Exception
  36.             Throw
  37.         End Try
  38.         If shell IsNot Nothing Then
  39.             Try
  40.                 shortCut = CType(shell.CreateShortcut(Me.ShortcutFullName), IWshShortcut)
  41.             Catch ex As Exception
  42.                 Throw
  43.             End Try
  44.             If shortCut IsNot Nothing Then
  45.                 shortCut.TargetPath = Me.TargetPath
  46.                 shortCut.WindowStyle = CInt(Me.WindowStyle)
  47.                 shortCut.Description = Me.Description
  48.                 shortCut.WorkingDirectory = Me.WorkingDirectory
  49.                 shortCut.IconLocation = String.Format("{0}, {1}", Me.IconPath, Me.IconIndex)
  50.                 shortCut.Arguments = Me.Arguments
  51.                 If Not String.IsNullOrWhiteSpace(Me.Hotkey) Then
  52.                     shortCut.Hotkey = Me.Hotkey
  53.                 End If
  54.  
  55.                 Try
  56.                     shortCut.Save()
  57.                     retval = System.IO.File.Exists(Me.ShortcutFullName)
  58.                 Catch ex As Exception
  59.                     Throw
  60.                 End Try
  61.             End If
  62.         End If
  63.         Return retVal
  64.     End Function
  65. End Class

Come possiamo vedere, il metodo Save() (che, rispetto al corrispettivo della WshShortcut restituisce un risultato) esegue i seguenti passi:

1) Crea un istanza della classe WshShell:

  1. Dim shell As WshShell = Nothing
  2. Try
  3.     shell = New WshShell()
  4. Catch ex As Exception
  5.     Throw
  6. End Try

2) Se l’istanza della shell è stata effettivamente creata, crea un’istanza della classe WshShortcut:

  1. Try
  2.     shortCut = CType(shell.CreateShortcut(Me.ShortcutFullName), IWshShortcut)
  3. Catch ex As Exception
  4.     Throw
  5. End Try

3) Se l’istanza dello shortcut è stata creata, vengono valorizzate le proprietà:

  1. shortCut.TargetPath = Me.TargetPath
  2. shortCut.WindowStyle = CInt(Me.WindowStyle)
  3. shortCut.Description = Me.Description
  4. shortCut.WorkingDirectory = Me.WorkingDirectory
  5. shortCut.IconLocation = String.Format("{0}, {1}", Me.IconPath, Me.IconIndex)
  6. shortCut.Arguments = Me.Arguments
  7. If Not String.IsNullOrWhiteSpace(Me.Hotkey) Then
  8.     shortCut.Hotkey = Me.Hotkey
  9. End If

4) Viene richiamato il metodo Save() della classe WshShortcut e controllato che il file lnk è effettivamente stato creato:

  1. Try
  2.     shortCut.Save()
  3.     retval = System.IO.File.Exists(Me.ShortcutFullName)
  4. Catch ex As Exception
  5.     Throw
  6. End Try

Un possibile utilizzo della classe è il seguente:

  1. Dim desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
  2. Dim shortcutFullname = System.IO.Path.Combine(desktop, "Doc.lnk")
  3. Dim shortcut = New Shortcut(shortcutFullname)
  4. shortcut.WindowStyle = ShortcutWindowsStyle.NormalNoFocus
  5. shortcut.Description = "I miei documenti"
  6. shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
  7. shortcut.Save()

In questo esempio viene creato un link chiamato Doc.lnk sul desktop dell’utente che permette l’apertura dei documenti.

Per concludere osserviamo che una delle proprietà della classe Shortcut da noi creata è l’enumerazione:

  1. Public Enum ShortcutWindowsStyle
  2.     NormalFocus = WshWindowStyle.WshNormalFocus
  3.     NormalNoFocus = WshWindowStyle.WshNormalNoFocus
  4.     MaximizedFocus = WshWindowStyle.WshMaximizedFocus
  5.     MinimizeFocus = WshWindowStyle.WshMinimizedFocus
  6.     MinimizedNoFocus = WshWindowStyle.WshMinimizedNoFocus
  7.     Hide = WshWindowStyle.WshHide
  8. End Enum

che definisce i possibili valori dello stile della finestra dello shortcut incapsulando l’analoga enumerazione WshWindowStyle della IWshRuntimeLibrary.

 

1 commento:

byman ha detto...

Salve, mi rendo conto che questo commento fa rifermento ad un vecchissimo post , ma ho trovato una classe che potrebbe tornarmi utile.
Cio che voglio creare è uno shortcut che punti all'applicazione vb con l'aggiunta di un parametro che è presente in un campo.
Cosi facendo lo shotcut aprirà l'applicazione che l'ha generato passandogli come parametro il valore catturato al momento della creazione dello shortcut.
Il programma si preoccuperà di aprire la scheda con quel codice.

Ho provato ad aggiungere la dll tramite COM "Script host object model", ho creato una classe e gli ho copiata quella presente su questo blog.
L'errore è su questa riga:
Public Property WindowStyle As ShortcutWindowsStyle = ShortcutWindowsStyle.NormalFocus

=> Errore BC30002
Il tipo 'ShortcutWindowsStyle' non è definito.

Ho provato ha cercare con google "ShortcutWindowsStyle" ma questa parola si trova soltanto su questo blog.

Un aiuto?
grazie mille in anticipo