Pregunta

Tengo este pedazo de código que funciona muy bien y me da la ruta del menú de inicio del usuario:

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

Esto, obviamente, utiliza el enlace en tiempo. Ahora digo que quiero hacer esto en C # o VB.NET en modo estricto, ninguno de los cuales apoyar este tipo de sintaxis con el enlace en tiempo.

¿Es esto posible? ¿Cómo?

Gracias por su ayuda!

¿Fue útil?

Solución

Si desea resolver este modo, el COM que tiene que averiguar, qué referencia COM para agregar en su proyecto de VB.

Abrir regedit y vaya a HKEY_CLASSES_ROOT\<class id>\CLSID, es decir.

HKEY_CLASSES_ROOT\Shell.Application\CLSID

y encontrará el ID de clase que identifica únicamente el componente COM.

Bajo HKEY_CLASSES_ROOT\CLSID ahora se puede buscar el archivo que está detrás de la componente COM:

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

muestra el siguiente valor:

%SystemRoot%\system32\SHELL32.dll

Ahora vaya a Visual Studio, y añadir una referencia a este archivo (en el Examinar ficha de los Agregar referencia de diálogo). Si abre las propiedades de proyectos, en realidad ver que el buen nombre del componente COM añadido es Controles de Microsoft Shell y Automatización .

Una vez que se añade la referencia se puede utilizar el objeto Shell.Application de la siguiente manera:

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 versión en C # se vería de la siguiente manera:

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

Sin embargo, si sólo hay que recuperar la ubicación de la carpeta del menú Inicio se puede hacer lo mismo directamente en .NET utilizando

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

Otros consejos

Bueno, en realidad se podría utilizar la reflexión:

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

No es el tipo de código que me gusta, pero en C # 4.0 se puede utilizar el tipo dinámico para limpiar este desastre.

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

aquí por más.

Si no recuerdo mal, todo lo que tiene que hacer es echar la referencia de objeto en la interfaz apropiada. Si utiliza un objeto COM en .NET, que normalmente importar la biblioteca de tipos y luego tener las interfaces disponibles.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top