2010-07-29 50 views
0

我使用VS2008开发一个excel 2007加载项,在加载项内我想使用Activation Context API来实例化一个COM类。无法在Windows XP/2003的Excel 2007加载项中使用Activation Context API?

奇怪的是我可以在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中指定的目录。

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

回答

2

只是在XP/2003中,Activation Context API不尊重lpAssemblyDirectory,如果您将lpSource指向的根文件清单中的COM文件信息放在该清单中,则在此情况下,Windows将只搜索可执行文件的目录中的COM文件驻留在。

解决方法是创建另一个mainfest,它依赖于原始清单ComViewer.x.manifest并将其传递到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为好。

+0

我已经尝试过您的方法,但无法弄清楚如何将清单链接在一起。你能否扩展关于“应该添加元素”的最后一句话?能够看到两个名单都有他们的名字和简短的描述一切如何工作是很棒的,例如,谁调用谁和为什么。 – Mikhail 2014-02-19 01:24:24

相关问题