Использование раннего связывания для COM-объекта - PullRequest
3 голосов
/ 22 апреля 2009

У меня есть этот кусок кода, который работает очень хорошо и дает мне путь к меню «Пуск» пользователя:

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

Это очевидно использует позднюю привязку. Теперь скажите, что я хочу сделать это в C # или в строгом режиме VB.NET, ни один из которых не поддерживает этот тип синтаксиса с поздним связыванием.

Возможно ли это? Как?

Спасибо за помощь!

Ответы [ 4 ]

4 голосов
/ 22 апреля 2009

Если вы хотите решить эту проблему с помощью COM, вам нужно выяснить, какую ссылку COM добавить в ваш проект VB.

Откройте regedit и перейдите к HKEY_CLASSES_ROOT\<class id>\CLSID, т.е.

HKEY_CLASSES_ROOT\Shell.Application\CLSID

и вы найдете идентификатор класса, который однозначно идентифицирует компонент COM.

Под HKEY_CLASSES_ROOT\CLSID теперь вы можете посмотреть, какой файл находится за компонентом COM:

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

показывает следующее значение:

%SystemRoot%\system32\SHELL32.dll

Теперь перейдите в Visual Studio и добавьте ссылку на этот файл (на вкладке Обзор диалогового окна Добавить ссылки ). Если вы откроете свойства проектов, вы увидите, что добавленное имя COM-компонента называется Microsoft Shell Controls and Automation .

После добавления ссылки вы можете использовать объект Shell.Application следующим образом:

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

Версия на C # будет выглядеть следующим образом:

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

Однако, если вам просто нужно получить местоположение папки «Пуск», вы можете сделать то же самое прямо в .NET, используя

Dim path As String = System.Environment.GetFolderPath(Environment.SpecialFolder.StartMenu)
3 голосов
/ 22 апреля 2009

Ну, на самом деле вы могли бы использовать отражение:

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

Не тот код, который мне нравится, но в C # 4.0 вы можете использовать динамический тип , чтобы убрать этот беспорядок.

2 голосов
/ 22 апреля 2009
Dim DirPath As String = _
    System.Environment.GetFolderPath(Environment.SpecialFolder.StartMenu)

См. здесь для получения дополнительной информации.

0 голосов
/ 22 апреля 2009

Если я правильно помню, все, что вам нужно сделать, это привести ссылку на объект в соответствующий интерфейс. Если вы используете COM-объект в .NET, вы обычно импортируете библиотеку типов, а затем получаете готовые интерфейсы.

...