You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何连接到非预览的第二个Word OLE实例(多进程共享)

问题背景与需求

我们有一个模块用Word预览旧格式(.DOC)文档,另有其他模块通过OLE打开Word实例处理文档。当前需求是仅创建一个具备完整功能的Word实例(非预览/嵌入式实例,这类实例没有功能区、菜单等),且支持多个进程连接该实例。

已知GetActiveObject可以获取Word实例,但它只返回第一个实例,如果该实例是预览/嵌入式的,就需要忽略它并创建新实例。现在要实现找到并连接第二个正常Word实例的功能,相关代码及修改尝试如下:

原代码片段

hr := GetActiveObject(ClassID, nil, unknown);
if Succeeded(hr) then
begin
   // Instance is running - get the IDispatch interface
   isRunning := true;
   OleCheck(unknown.QueryInterface(IDispatch, dispatch));
   Result := dispatch;
   // Is the instance visible? If not, then we need to launch a new instance. Denotes a preview instance.
   isVisible := Result.Visible;
end;
// Only launch a new instance of Word if requested or isVisible is False.
if ((not isRunning) or (not isVisible)) or createInstance then
begin
   // Trying to find the right instance of Word. Experimental...
   isAssigned := False;
   if GetRunningObjectTable(0, ROT) = S_OK then
   begin
      if ROT.EnumRunning(enumMon) = S_OK then
      begin
         CreateBindCtx(0, Bind);
         while enumMon.Next(1, Moniker, Count) = S_OK do
         begin
            Moniker.GetDisplayName(Bind, Nil, DN);
            // This is the instance we want, and we get it...
            if pos('normal.dotm', Lowercase(DN)) > 0 then
            begin
               // What should be here to return the OLE Object?
               if Moniker.BindToObject(Bind, nil, IDispatch, Result) = S_OK then
               begin
                  isAssigned := True;
                  Break;
               end;
            end;
         end;
      end;
   end;
   // Create a new instance
   if (not isAssigned) or createInstance then
   begin
      OleCheck(CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IDispatch, dispatch));
      Result := dispatch;
   end;
end;

修改尝试片段

// What should be here to return the Object?
if Moniker.BindToObject(Bind, nil, IDispatch, Unknown) = S_OK then
begin
   OleCheck(unknown.QueryInterface(IDispatch, dispatch));
   Result := dispatch;
   isAssigned := True;
   Break;
end;
if Moniker.BindToObject(Bind, nil, IDispatch, Unknown) = S_OK then
begin
   OleCheck(unknown.QueryInterface(IDispatch, dispatch));
   WordObj := dispatch;
   Result := WordObj.Application;
   isAssigned := True;
   Break;
end;

内容的提问来源于stack exchange,提问作者David OBrien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 09:21:05