Pergunta

Eu tenho este pedaço de código que funciona muito bem e me dá o caminho do menu Iniciar do usuário:

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

Isto, obviamente, usa a ligação tardia. Agora dizer que eu quero fazer isso em C #, ou no modo estrito VB.NET, nenhum dos quais apoiar este tipo de sintaxe com a ligação tardia.

Isso é possível? Como?

Obrigado por você ajuda!

Foi útil?

Solução

Se você quiser resolver desta forma o COM você tem que descobrir, que a referência COM para adicionar em seu projeto VB.

Abra o regedit e navegue até HKEY_CLASSES_ROOT\<class id>\CLSID, i.

HKEY_CLASSES_ROOT\Shell.Application\CLSID

e você vai encontrar o ID de classe que identifica exclusivamente o componente COM.

Em HKEY_CLASSES_ROOT\CLSID agora você pode olhar para cima o arquivo que está por trás do componente COM:

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

mostra o seguinte valor:

%SystemRoot%\system32\SHELL32.dll

Agora vá para Visual Studio, e adicionar uma referência para este arquivo (no Procure guia do Adicionar Referências de diálogo). Se você abrir as propriedades de projetos, você realmente verá que o bom nome do componente COM adicional é Controles Microsoft Shell e Automação .

Uma vez que a referência é adicionada, você pode usar o objeto Shell.Application da seguinte forma:

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

A versão em C # ficaria da seguinte forma:

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

No entanto, se você simplesmente precisa para recuperar a localização do Menu Iniciar pasta que você pode fazer o mesmo diretamente no .NET usando

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

Outras dicas

Bem, na verdade você poderia usar a reflexão:

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

Não é o tipo de código que eu gosto, mas em C # 4.0, você poderia usar o tipo dinâmico para limpar essa bagunça.

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

Consulte aqui para mais.

Se bem me lembro, tudo que você tem a fazer é lançar a referência do objeto para a interface apropriada. Se você usar um objeto COM em .NET, você normalmente importar a biblioteca de tipos e depois ter as interfaces disponíveis.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top