Domanda

Ho questo pezzo di codice che funziona molto bene e mi dà il percorso di menu di avvio dell'utente:

    Dim oShell As Object = CreateObject("Shell.Application")
    MsgBox(oShell.NameSpace(11).Self.Path)

Questo utilizza, ovviamente, l'associazione tardiva. Ora dico che voglio fare questo in C # o VB.NET in modalità rigorosa, nessuno dei quali supporta questo tipo di sintassi con l'associazione tardiva.

È possibile? Come?

Grazie per l'aiuto!

È stato utile?

Soluzione

Se si vuole risolvere in questo modo il COM si deve capire, che riferimento COM per aggiungere nel progetto VB.

Apri regedit e passare alla HKEY_CLASSES_ROOT\<class id>\CLSID, cioè.

HKEY_CLASSES_ROOT\Shell.Application\CLSID

e troverete l'id classe che identifica in modo univoco il componente COM.

Sotto HKEY_CLASSES_ROOT\CLSID è ora possibile cercare il file che si trova dietro il componente COM:

HKEY_CLASSES_ROOT\CLSID\{13709620-C279-11CE-A49E-444553540000}\InProcServer32

indica il seguente valore:

%SystemRoot%\system32\SHELL32.dll

Ora vai a Visual Studio, e aggiungere un riferimento a questo file (sulla Sfoglia scheda delle Aggiungi riferimento finestra di dialogo). Se si apre le proprietà dei progetti, sarà effettivamente vedere che il bel nome del componente COM aggiunto è Controlli Microsoft Shell e Automazione .

Una volta aggiunto il riferimento è possibile utilizzare l'oggetto Shell.Application come segue:

Option Strict On

Module PrintStartMenuLocation

    Sub Main()
        Dim shell As New Shell32.Shell
        Dim folder As Shell32.Folder
        Dim folderItem As Shell32.FolderItem
        Dim startMenuPath As String

        folder = shell.NameSpace(Shell32.ShellSpecialFolderConstants.ssfSTARTMENU)
        folderItem = CType(folder.Items(0), Shell32.FolderItem)
        startMenuPath = folderItem.Path

        Console.WriteLine(startMenuPath)
    End Sub

End Module

Una versione in C # apparirebbe come segue:

class Program
{
    static void Main(string[] args)
    {
        Shell32.Shell shell = new Shell32.Shell();
        Shell32.Folder folder = shell.NameSpace(Shell32.ShellSpecialFolderConstants.ssfSTARTMENU);
        Shell32.FolderItem folderItem = folder.Items().Item(0) as Shell32.FolderItem;
        string startMenuPath = folderItem.Path;

        Console.WriteLine(startMenuPath);
    }
}

Tuttavia, se semplicemente bisogno di recuperare la posizione della cartella Menu Avvio si può fare lo stesso direttamente nel .NET utilizzando

Dim path As String = System.Environment.GetFolderPath(Environment.SpecialFolder.StartMenu)

Altri suggerimenti

Beh in realtà si potrebbe utilizzare la riflessione:

Type shellType = Type.GetTypeFromProgID("Shell.Application", true);
object shell = Activator.CreateInstance(shellType);
object folder = shellType.InvokeMember("NameSpace", BindingFlags.InvokeMethod, null, shell, new object[] { 11 });
object self = folder.GetType().InvokeMember("Self", BindingFlags.GetProperty, null, folder, new object[] { });
object path = self.GetType().InvokeMember("Path", BindingFlags.GetProperty, null, self, new object[] { });
Console.WriteLine(path);

Non è il tipo di codice che mi piace, ma in C # 4.0 è possibile utilizzare il tipo dinamico per ripulire questo pasticcio.

Dim DirPath As String = _
    System.Environment.GetFolderPath(Environment.SpecialFolder.StartMenu)

qui per più.

Se non ricordo male, tutto ciò che dovete fare è di lanciare il riferimento all'oggetto nell'interfaccia appropriata. Se si utilizza un oggetto COM in .NET, in genere importare la libreria dei tipi e quindi avere le interfacce prontamente disponibili.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top