Tag: com

如何使用.NET升级COM组件

我发现了一篇关于如何通过调用CoCreateInstanceAsAdmin来提升用C ++编写的COM对象的文章 。 但是我无法找到或做的是将.NET(c#)应用程序的一个组件实现为COM对象,然后调用该对象来执行需要UAC提升的任务。 MSDN将此文档记录为管理COM对象模型 。 我知道以管理员身份启动应用程序(或其他应用程序)是可能的,并且很容易在单独的过程中执行任务(例如参见Daniel Moth的post ,但我正在寻找的是一种方式从同一个未提升的.NET可执行文件中做所有事情。当然,这样做会在新进程中生成COM对象,但是由于透明的编组,.NET COM对象的调用者不应该(也是很多)意识到这一点。 关于如何使用C#项目,通过CoCreateInstanceAsAdmin API实现用C#编写的COM对象的任何想法都会非常有用。 所以我真的很想学习如何在C#中编写COM对象,然后我可以通过COM高程API从C#调用它。 不要紧,boost的COM对象是否在同一进程中运行。 我只是不想让整个应用程序升级; 我只想提升将执行代码的COM对象。 如果我能写出一些东西: // in a dedicated assembly, marked with the following attributes: [assembly: ComVisible (true)] [assembly: Guid (“….”)] public class ElevatedClass { public void X() { /* do something */ } } 然后让我的主应用程序通过CoCreateInstanceAsAdmin调用实例化ElevatedClass 。 但也许我只是在做梦。

从C#调用MATLAB函数

我开发了一个MATLAB函数,我正在寻找一种方法从另一个C#应用程序调用该函数并将一些参数传递给它并在C#程序中获得结果。 我听说我可以使用动态数据交换 (DDE)或COM对象,但我能做到吗?

在C#中使用COM互操作时的RCW和引用计数

我有一个使用Office互操作程序集的应用程序。 我知道运行时管理的“运行时可调用包装器(RCW)”。 但我不太确定引用计数如何增加。 MSDN说, RCW只保留对包装的COM对象的一个​​引用,而不管调用它的受管客户端的数量。 如果我理解正确,在以下示例中, using Microsoft.Office.Interop.Word; static void Foo(Application wrd) { /* …. */ } static void Main(string[] args) { var wrd = new Application(); Foo(wrd); /* …. */ } 我将实例wrd传递给另一个方法。 但这不会增加内部引用计数。 所以我想知道引用计数增加的场景是什么? 任何人都可以指出引用计数增加的情况吗? 另外我读了一些博客,说在使用COM对象编程时避免使用双点。 像wrd.ActiveDocument.ActiveWindow这样的东西。 作者声称编译器创建单独的变量来保存将增加引用计数器的值。 恕我直言,这是错误的,第一个例子certificate了这一点。 那是对的吗? 任何帮助都会很棒!

从Javascript调用C#BHO方法

我正试图弄清楚如何在页面内的Javascript中调用我的BHO对象中的C#方法。 我在C ++ / ATL / Com中找到了很多关于如何做的页面,例如: 浏览器帮助程序对象和脚本选项 从Javascript调用BHO方法? 我试图在C#中正确地实现它,但我无法让它工作,可能是因为我有一些我不明白的COM问题。 我正在使用C#4.0。 以下是代码的相关部分: using SHDocVw; using mshtml; using System.Runtime.InteropServices; [ComVisible(true), Guid(“300736C4-DCDA-4DB0-90AD-4510A12EBBC6”), ClassInterface(ClassInterfaceType.None), ProgId(“My Extension”)] public class BrowserHelperObject : IObjectWithSite { const int DISPATCH_PROPERTYPUT = 4; const int FDEX_NAME_ENSURE = 2; const uint LOCALE_USER_DEFAULT = 0x0400; WebBrowser browser; … public void OnDocumentComplete(dynamic frame, ref dynamic url) { […]

VSTO加载项,COMAddIns和RequestComAddInAutomationService

请参阅1st Edit (底部的屏幕截图): 我已经按照本文的说法让Winform应用程序触发VSTO加载项方法: http : //blogs.msdn.com/b/andreww/archive/2007/01/15/vsto-add-ins-comaddins-and -requestcomaddinautomationservice.aspx 在上面的文章的最后,作者提到了一个问题,并试图在这里改进它: http : //blogs.msdn.com/b/andreww/archive/2008/08/11/why-your-comaddin-object-should -derive从- standardolemarshalobject.aspx 我现在已经多次通过代码,并且派生StandardOleMarshalObject以改善exception的方法不起作用 ! System.InvalidCastException: Unable to cast COM object of type ‘System.__ComObject’ to interface type … This operation failed because the QueryInterface call on the COM component for the interface with IID 这是一个repro – 两个项目的目标.Net 3.5: a)创建新的Office> 2007或2010> Excel加载项: namespace ExcelAddIn1 { […]

从C#调用IDispatch COM接口的成员

我想从COM对象调用GetIdsOfNames函数,该对象在c#中实现IDispatch接口。 我编写了以下代码,但它失败了DISP_E_UNKNOWNNAME。 这是正确的做法吗? Object so = Activator.CreateInstance(Type.GetTypeFromProgID(“ProgID”)); Object[] args = new Object[5]; string[] rgsNames = new string[1]; rgsNames[0] = “PrintNormal”; uint LOCALE_SYSTEM_DEFAULT = 0x0800; uint lcid = LOCALE_SYSTEM_DEFAULT; int cNames = 1; int[] rgDispId = new int[1]; args[0] = IntPtr.Zero; args[1] = rgsNames; args[2] = cNames; args[3] = lcid; args[4] = rgDispId; Object result = […]

为什么我不能将我的COM对象转换为它在C#中实现的接口?

我在dll中有这个接口(此代码在元数据中显示在Visual Studio中): #region Assembly XCapture.dll, v2.0.50727 // d:\svn\dashboard\trunk\Source\MockDiagnosticsServer\lib\XCapture.dll #endregion using System; using System.Runtime.InteropServices; namespace XCapture { [TypeLibType(4160)] [Guid(“XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX”)] public interface IDiagnostics { [DispId(1)] void GetStatusInfo(int index, ref object data); } } 所以我用这样的类创建了一个COM服务器: [ComVisible(true)] [Guid(SimpleDiagnosticsMock.CLSID)] [ComDefaultInterface(typeof(IDiagnostics))] [ClassInterface(ClassInterfaceType.None)] public class SimpleDiagnosticsMock : ReferenceCountedObject, IDiagnostics { public const string CLSID = “281C897B-A81F-4C61-8472-79B61B99A6BC”; // These routines perform the additional […]

处理来自托管STA应用程序中的进程外COM服务器的事件

显然,来自非托管进程外COM服务器的事件的托管处理程序在随机池线程上调用,而不是在主STA线程上调用(正如我所期望的那样)。 我在回答有关Internet Explorer自动化的问题时发现了这一点。 在下面的代码中, DocumentComplete在非UI线程上触发(因此”Event thread”与调试输出中的”Main thread” )。 因此,我必须使用this.Invoke来显示一个消息框。 据我所知,此行为与非托管COM客户端不同,其中从STA线程订阅的事件会自动编组回同一个线程。 这种背离传统COM行为背后的原因是什么? 到目前为止,我还没有找到任何证实这一点的参考文献。 using System; using System.Diagnostics; using System.Threading; using System.Windows.Forms; namespace WinformsIE { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs ev) { var ie = (SHDocVw.InternetExplorer)Activator.CreateInstance(Type.GetTypeFromProgID(“InternetExplorer.Application”)); ie.Visible = true; Debug.Print(“Main thread: {0}”, Thread.CurrentThread.ManagedThreadId); ie.DocumentComplete += […]

如何使用Regsvr32注册用C#编写的COM DLL?

我有一个使用COM DLL的VB6应用程序。 DLL是用C#编写的。 在C#项目属性中,我选中了“注册COM互操作”选项。 VB6应用程序在我的开发机器上运行良好。 C#代码完全遵循以下格式: CodeProject C#COM示例 当部署到其他计算机时,Regsvr32.exe在我尝试注册DLL时出现以下错误: The module “MyCOM.dll” was loaded but the entry-point DLLRegisterServer was not found. 这是什么意思? 没有教程/文档我读过关于COM DLL的任何关于“入口点DLLRegisterServer”的内容。 我们在不同的机器上使用RegAsm.exe时遇到了MAJOR问题,所以我们真的需要一个解决方案,我们可以运行regsvr32.exe,它可以用于我们部署到的任何机器(即XP,Vista,Windows 7,x86机器,x64)机器等) 我需要将哪些内容添加到我的C#代码中以使其可以使用regsvr32.exe进行注册?

释放临时COM对象

使用COM对象考虑以下C#代码。 MyComObject o = new MyComObject; try { var baz = o.Foo.Bar.Baz; try { // do something with baz } finally { Marshal.ReleaseComObject(baz); } } finally { Marshal.ReleaseComObject(o); } 这将释放COM对象o和baz ,但不释放由o.Foo和o.Foo.Bar的临时对象。 当这些对象拥有大量非托管内存或其他资源时,这可能会导致问题。 一个明显但丑陋的解决方案是,使用try-finally和Marshal.ReleaseComObject使代码更加混乱。 请参阅C#+ COM Interop,确定性版本 作为一种解决方法,我创建了一个帮助类 class TemporaryComObjects: IDisposable { public C T(C comObject) { m_objects.Add(comObject); return comObject; } public void Dispose() { foreach […]