0

我使用 VS2008 开发了一个 excel 2007 插件,在插件中我想使用 Activation Context API 来实例化一个 COM 类。

奇怪的是我可以在 Window 7 上成功实例化 COM 类,但在 Windows XP/2003 上 buf 失败。

这是代码片段

  string codeBase = this.GetType().Assembly.CodeBase;
  string asmFullPath = new Uri(codeBase).LocalPath;
  string comAssemblyPath = Path.GetDirectoryName(asmFullPath);

  ACTCTX ac = new ACTCTX();
  ac.cbSize = Marshal.SizeOf(typeof(ACTCTX));
  ac.lpAssemblyDirectory = comAssemblyPath;
  ac.lpSource = Path.Combine(comAssemblyPath, "ComViewer.x.manifest");
  ac.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;

  IntPtr cookie;
  IntPtr hActCtx = CreateActCtxW(ref ac);
  if (ActivateActCtx(hActCtx, out cookie))
  {
    try
    {
      //instantiate COM class
      IComViewer = new ComViewerClass();

    }
    finally
    {
      DeactivateActCtx(0, cookie);
    }
  }
  else
  {
    //TODO: Error message.
  }

COM 是用 C++ 编写的,清单如下所示:

在 Windows 2003/XP 上,我发现加载项在 c:\program files\microsoft Office\Office 12 中查找 ComViewer.dll 而不是我在 lpAssemblyDirectory 中指定的目录。

任何人都可以帮忙吗?提前致谢。

4

1 回答 1

2

请注意,在 XP/2003 中,如果您将 COM 文件信息放在 lpSource 指向的根清单中,则激活上下文 API 不尊重 lpAssemblyDirectory,在这种情况下,Windows 将仅在可执行文件所在的目录中搜索 COM 文件。

解决方法是创建另一个依赖于原始清单 ComViewer.x.manifest 的 mainfest,并将其传递给 lpSource。在上面的示例中,您可以传入以下清单:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity name="ComViewer.x" >
</assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>

当然,您也应该向 ComViewer.x.manifest 添加元素。

于 2010-08-03T13:08:08.920 回答