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.

 

mercoledì 29 dicembre 2010

Tiriamo le somme per il 2010

Il 2010 volge al termine ed è ora di tirare le somme della mia attività di blogger.

In quest’anno ho scrito 153 post (decisamente più prolifico rispetto all’anno precedente) e la classifica assoluta (contemplando anche quelli scritti negli anni precedenti) dei migliori 5 è la seguente:

  1. VB.NET: SplashScreen con effetto fade-in
  2. Appunti di WPF – Settima Puntata – Il Layout
  3. Cambiare la lingua di Visual Studio 2008
  4. VB.NET: Convertire un file DOC in RTF e PDF con office interop
  5. Appunti di WPF – Dodicesima Puntata – Le figure geometriche

Se analizziamo la classifica dei migliori post scritti nel 2010 otteniamo:

  1. Appunti di WPF – Settima Puntata – Il Layout
  2. Appunti di WPF – Dodicesima Puntata – Le figure geometriche
  3. Briciole di WPF: Finestre non rettangolari, WPF vs Windows Forms
  4. Appunti di WPF – Quarta Puntata – XAML, le basi
  5. Briciole di WPF – SplashScreen in Visual Studio 2010
Questa ultima dimostra l’interesse verso WPF ma anche l’interesse verso i tutorial.

Per questo motivo durante il 2011 cercherò di concentrarmi nella scrittura di tutorial per chi si avvicina al mondo .NET.

Alla fine di questo anno posso ritenermi soddisfatto delle visite ottenute sul blog (con oltre 13K totali e una media di circa 1K al mese). Lo scorso anno mi fermai a circa 3k di visite totali (è vero che il blog è stato aperto a fine aprile, ma in ogni caso il numero è decisamente aumentato). Va detto, ad onor di cronaca, che debbo ringraziare la community DomusDotNet e, prima ancora, la defunta DotNetRomaCestà perchè mi hanno dato visibilità.

Tutto questo mi sprona ad impegnarmi ancora durante il 2011 per fornire sempre materiale di quantità.

martedì 21 dicembre 2010

WP7 WebBrowser control e target=”_blank”

Il controllo WebBrowser dei tool di sviluppo di WP7 non digerisce bene gli anchor con target=”_blank”.

Se provate a visualizzare una pagina con dei link che hanno specificato il target impostato su “_blank”, questi non funzioneranno.

Se, invece, il link ha target “_top”, “_parent” o “_self” (o non ha target), il webbrowser vi permette tranquillamente di navigare seguendo i link.

Questo significa che se visualizzate delle pagine web che hanno l’apertura di nuove pagine, queste non funzioneranno come vi aspettate.

Se state utilizzando il metodo NavigateToString() per visualizzare un vostro html, accertatevi di non avere il target negli anchor ed il gioco è fatto.

 

mercoledì 15 dicembre 2010

Connessione a TFS tramite DOM in un servizio web

In un progetto a cui sto lavorando mi è capitato di dover accedere a TFS 2010/2008 utilizzando il DOM messo a disposizione dal Team Explorer.

Abbiamo che fare con un web service che permette di gestire chiamate da una piattaforma non microsoft analizzando il traffico e eseguendo un certo lavoro sui dati ma che, alla fine della fiera, scrive dei workitem all’interno di TFS e non abbiamo scelto di utilizzare la integration platform di TFS.

Lato client, il Team Explore utilizza una serie di cartelle di cache per “cachare” i dati in modo da ottimizzare l’accesso alla piattaforma TFS.

La cartella solitamente utilizzata è nel seguente percorso:

C:\Documents and Settings\Default User\Local Settings\Application Data\Microsoft\Team Foundation\3.0\Cache

In particolare, questa cartella viene creata dal Team Explorer nel momento in cui un utente si connette.

Il problema nasce dal fatto che un servizio web “gira” con un utente che non si connette mai e, quindi, non troverà mai tale cartella.

Per evitare questo problema, in tutti gli oggetti derivati dalla classe TfsConnection (ad esempio TfsConfigurationServer o TfsTeamProjectCollection) si può impostare la proprietà ClientSettingsDirectory che permette di settare la cartella da utilizzare per la cache.

Ovviamente la cartella dovrà avere gli opportuni privilegi in modo che il servizio web possa scrivere all’interno di essa.

La stessa proprietà può essere utilizzata da un servizio Windows o da un client standard a finestra.

 

Tutto cambia…..anche il natale!!!

 

Tag di Technorati: ,,

mercoledì 8 dicembre 2010

Rilasciata la Feature CTP5 di EF

E’ stato annunciato (vedi il post) il rilascio della Feature CTP5 di EF per lo sviluppo di classi di accesso alla banca dati di tipo Code First.

Sul blog di ADO.NET sono disponibili anche dei post per cominciare a capire il funzionamento del framework:

Questa è l’ultima CTP prima del rilascio definitivo che avverrà nel primo quadrimestre del 2011.

Per scaricare la CTP utilizzare il link.

mercoledì 1 dicembre 2010

IE9– Creare un’attività nella jumplist senza immagine

IE9 permette agli sviluppatori di definire delle attività all’interno della jumplist di un sito agganciato alla task bar di Windows 7 (vedere post per maggiori info).

Un’attività altro non è che un accesso rapido ad una funzionalità di un’applicazione che, nel caso di un web site,  è che una pagina.

Le attività si definiscono attraverso dei meta tag nel formato:

  1. <META name="msapplication-task"
  2.       content="name=News; action-uri=url della pagina; icon-uri=imagine del task" >

dove il content è formato da tre parti distinte:

  • name : nome che compare nella lista dei tasks. Può essere anche vuoto (anche se non ha molto senso perché l’utente vedrebbe un’attività senza alcun nome e non saprebbe a cosa serve);
  • action-uri : indirizzo della pagina che corrisponde al task. Può anche essere vuoto (in questo caso viene aperta la root del sito) oppure un link esterno al nostro sito;
  • icon-uri : immagine da utilizzare nella lista dei task alla sinistra del nome. Questo campo non può essere vuoto e deve puntare ad una immagine in formato ico.

Le tre parti devono essere presenti anche se, name e action-uti possono essere vuote.

La parte relativa all’immagine, invece, non può restare vuota, altrimenti il tag non è riconosciuto (è come se non ci fosse).

Se vogliamo implementare un’attività senza immagine ci basta inserire un valore qualsiasi anzichè lasciare il campo vuoto, ad esempio la stringa “null”.

Il seguente tag, per esempio, implementa l’attività News senza immagine:

  1. <META name="msapplication-task"
  2.       content="name=News; action-uri=news.html; icon-uri=null" >