在COM对象上使用早期绑定

4 浏览
0 Comments

在COM对象上使用早期绑定

我有一段代码,功能非常好,可以获取用户开始菜单的路径:

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

很明显,这是使用了后期绑定。现在,假设我想在C#或VB.NET严格模式中实现同样的功能,但这两种语言都不支持后期绑定的语法。

这有可能吗?怎么做?

谢谢你的帮助!

0
0 Comments

使用早期绑定的COM对象的问题出现的原因是没有正确添加COM引用。解决方法是通过注册表查找COM组件的类ID,并添加对应的引用。

首先,打开注册表编辑器(regedit),然后导航到,例如,这里可以找到唯一标识COM组件的类ID。

接下来,在下查找该COM组件对应的文件:,可以看到该键的值为%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)

0
0 Comments

使用早期绑定的COM对象的问题可能出现的原因是想要使用早期绑定。

解决方法是使用动态类型来简化代码。以下是使用动态类型解决问题的示例代码:

dynamic shellType = Type.GetTypeFromProgID("Shell.Application", true);

dynamic shell = Activator.CreateInstance(shellType);

dynamic folder = shellType.InvokeMember("NameSpace", BindingFlags.InvokeMethod, null, shell, new object[] { 11 });

dynamic self = folder.GetType().InvokeMember("Self", BindingFlags.GetProperty, null, folder, new object[] { });

dynamic path = self.GetType().InvokeMember("Path", BindingFlags.GetProperty, null, self, new object[] { });

Console.WriteLine(path);

0
0 Comments

使用早期绑定(early binding)时遇到的一个问题是,无法通过编译器进行类型检查,因此可能会在运行时出现错误。早期绑定是指在编译时将对象的类型确定下来,并在代码中直接使用对象的方法和属性。

在这个例子中,我们使用了一个COM对象,并尝试获取特殊文件夹的路径。我们使用了特殊文件夹枚举(Environment.SpecialFolder.StartMenu)来指定要获取的文件夹类型。

然而,由于使用了早期绑定,编译器无法确定COM对象的确切类型,因此无法进行类型检查。这可能会导致在运行时出现错误,特别是当COM对象的类型与编译时使用的类型不匹配时。

为了解决这个问题,我们可以使用晚期绑定(late binding)来代替早期绑定。晚期绑定是指在运行时根据对象的实际类型来决定要调用的方法和属性。这样可以避免在编译时出现类型不匹配的错误。

下面是使用晚期绑定来修改代码的示例:

Dim obj As Object = CreateObject("COMObject")
Dim DirPath As String = obj.GetFolderPath(Environment.SpecialFolder.StartMenu)

在这个示例中,我们首先创建了一个Object类型的变量obj,并使用CreateObject函数来实例化COM对象。然后,我们可以通过obj变量来调用COM对象的方法和属性,而不需要使用早期绑定。

通过使用晚期绑定,我们可以避免在编译时出现类型不匹配的错误,并且可以确保在运行时正确地调用COM对象的方法和属性。这样可以提高代码的健壮性和可靠性。

,使用早期绑定时可能会导致类型不匹配的错误。为了解决这个问题,我们可以使用晚期绑定来确保在运行时正确地调用COM对象的方法和属性。

0