VBIDE COM插件开发:创建可停靠工具窗口失败(HRESULT 0x800401F3)
VBIDE扩展创建可停靠工具窗口时HRESULT 0x800401F3错误解决
问题描述
开发VBIDE扩展时,调用CreateToolWindow方法创建可停靠工具窗口时触发HRESULT 0x800401F3错误,出错代码行如下:
_window = windows.CreateToolWindow( _addin, "VBAaddin.TestComponent", "My CoolDoc", guid, ref control );
相关代码
扩展主类代码
using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Windows.Forms; using Extensibility; using Microsoft.Vbe.Interop; using VB = Microsoft.Vbe.Interop; namespace VBAaddin { [ ComVisible(true), ProgId("VBAaddin.Extension"), Guid("60A72993-8B93-4C71-81E8-87BC6DD85F5D"), ClassInterface(ClassInterfaceType.None), ComDefaultInterface(typeof(IDTExtensibility2)), EditorBrowsable(EditorBrowsableState.Never) ] public class Extension : IDTExtensibility2 { private VB.VBE _vbe; private VB.AddIn _addin; private VB.Window _window; public void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom) { _vbe = (VB.VBE)Application; _addin = (VB.AddIn)AddInInst; switch (ConnectMode) { case ext_ConnectMode.ext_cm_Startup: break; case ext_ConnectMode.ext_cm_AfterStartup: InitializeExtension(); break; } } private void InitializeExtension() { MessageBox.Show("Initializing"); try { try { object control = null; const string guid = "9A195073-D54B-4FFD-883C-EBBBEFD860F5"; Windows windows = _vbe.Windows; _window = windows.CreateToolWindow( _addin, "VBAaddin.TestComponent", "My CoolDoc", guid, ref control ); _window.Visible = true; } catch (COMException exception) { MessageBox.Show(exception.ToString()); } } catch (Exception e) { MessageBox.Show($"{e.Message} {e.Source}"); } } public void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom) { } public void OnAddInsUpdate(ref Array custom) { } public void OnStartupComplete(ref Array custom) { InitializeExtension(); } public void OnBeginShutdown(ref Array custom) { } } }
TestComponent代码
using System.Runtime.InteropServices; using System.Windows.Controls; namespace VBAaddin { [ ComVisible(true), ProgId("VBAaddin.TestComponent"), Guid("9A195073-D54B-4FFD-883C-EBBBEFD860F5") ] public partial class TestComponent : UserControl { public TestComponent() { InitializeComponent(); } } }
TestComponent.xaml代码
<UserControl x:Class="VBAaddin.TestComponent" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:VBAaddin" mc:Ignorable="d" d:DesignHeight="200" d:DesignWidth="300"> <Grid> <TextBox HorizontalAlignment="Center" Margin="0,82,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/> </Grid> </UserControl>
注册表配置
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Microsoft\VBA\VBE\6.0\Addins\VBAaddin.Extension] "Description"="VBAaddin" "FriendlyName"="VBAaddin" "LoadBehavior"=dword:00000003 [HKEY_CURRENT_USER\Software\Microsoft\VBA\VBE\6.0\Addins64\VBAaddin.Extension] "Description"="VBAaddin" "FriendlyName"="VBAaddin" "LoadBehavior"=dword:00000003 [HKEY_CLASSES_ROOT\CLSID\{60A72993-8B93-4C71-81E8-87BC6DD85F5D}] @="VBAaddin.Extension" [HKEY_CLASSES_ROOT\CLSID\{60A72993-8B93-4C71-81E8-87BC6DD85F5D}\ProgId] @="VBAaddin.Extension" [HKEY_CLASSES_ROOT\VBAaddin.Extension] @="VBAaddin.Extension" [HKEY_CLASSES_ROOT\VBAaddin.Extension\CLSID] @="{60A72993-8B93-4C71-81E8-87BC6DD85F5D}" [HKEY_CLASSES_ROOT\VBAaddin.TestComponent] @="VBAaddin.TestComponent" [HKEY_CLASSES_ROOT\CLSID\{9A195073-D54B-4FFD-883C-EBBBEFD860F5}] @="VBAaddin.TestComponent" [HKEY_CLASSES_ROOT\VBAaddin.TestComponent\CLSID] @="{9A195073-D54B-4FFD-883C-EBBBEFD860F5}"
错误原因及修复方案
HRESULT 0x800401F3对应CO_E_CLASSSTRING,表示无法找到指定的COM类,问题出在COM组件注册或控件类型不兼容上,具体修复步骤如下:
修复TestComponent的COM注册:当前注册表缺少TestComponent的
InprocServer32项,这是COM组件必需的注册项。使用对应位数的regasm.exe重新注册dll:- 32位Office:使用
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe - 64位Office:使用
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe
执行命令:
regasm /codebase /tlb YourAddinDllPath.dll该命令会自动添加
InprocServer32项并生成类型库,确保VBIDE能识别到该COM类。- 32位Office:使用
替换控件类型为Windows Forms控件:VBIDE的
CreateToolWindow仅支持ActiveX控件,直接使用WPF UserControl无法被识别。可选择:- 在Windows Forms UserControl中添加
WindowsFormsHost承载WPF控件 - 直接将TestComponent改为继承自
System.Windows.Forms.UserControl,用WinForms控件构建界面
- 在Windows Forms UserControl中添加
确保位数匹配:Office的位数(32/64位)必须与扩展dll的编译位数一致,在项目属性生成选项中设置目标平台为
x86(对应32位Office)或x64(对应64位Office),不要使用Any CPU。验证CLSID和ProgID一致性:确保
CreateToolWindow中传入的guid参数与TestComponent的Guid属性完全一致(大括号可保留或去掉,注册表支持两种格式,但代码中需匹配)。
内容的提问来源于stack exchange,提问作者artodoro
相关产品推荐
相关产品推荐

