Tag: com

在C#中释放COM对象

我知道这已经讨论过了,但我找不到满意的答案。 我有一个电子邮件文件(.msg),我打开如下,然后调用显示。 oApp = new Microsoft.Office.Interop.Outlook.Application(); mail = (Microsoft.Office.Interop.Outlook.MailItem)oApp.Session.OpenSharedItem(fileName); mail.Display(false); oApp = null; // do I need to release this object ? 用户可以关闭它并重新打开它。 在他们点击“重新打开”之前,我检查窗口是否仍然存在,如果是,那么只需将SetForeground(hwnd)发送到该窗口。 如果不是,那意味着用户关闭了它,所以只需释放mailItem对象并再次打开。 public static void ReleaseCOMObject(Microsoft.Office.Interop.Outlook.MailItem item) { int r = System.Runtime.InteropServices.Marshal.ReleaseComObject(item); while (r != 0) { r = System.Runtime.InteropServices.Marshal.ReleaseComObject(item); } } 如果我再次尝试打开同一个文件。 它“有时”会抛出“正在使用的文件exception”所以,我认为即使我发布了MailItem,它也没有被正确发布。 我该怎么做才能确保其正确发布。 关闭和重新打开文件是一种非常常见的情况。 任何指针都会非常有用。

在WinForms线程上使用CoInitializeEx

我正在为DSLR相机制作SDK,其中包含以下说明: 开发Windows应用程序的注意事项创建在Windows下运行的应用程序时,每个线程都需要进行COM初始化,以便从主线程以外的线程访问摄像机。 要创建用户线程并从该线程访问摄像机,请确保在线程的开头执行CoInitializeEx(NULL,COINIT_APARTMENTTHREADED),最后执行CoUnInitialize()。 示例代码如下所示。 从另一个线程控制EdsVolumeRef或EdsDirectoryItemRef对象时,这是相同的,而不仅仅是EdsCameraRef。 void TakePicture(EdsCameraRef camera) { // Executed by another thread HANDLE hThread = (HANDLE)_beginthread(threadProc, 0, camera); // Block until finished ::WaitForSingleObject( hThread, INFINITE ); } void threadProc(void* lParam) { EdsCameraRef camera = (EdsCameraRef)lParam; CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ); EdsSendCommand(camera, kEdsCameraCommand_TakePicture, 0); CoUninitialize(); _endthread(); } 我的应用程序是一个C#WinForms应用程序,通常,我使用托管线程类和Control.Invoke函数来避免跨线程问题。 由于我在C#中没有使用SDK的示例源代码,我的问题是,在标有[STAThread]属性的应用程序中使用CoInitializeEx是否有用和/或必要? 我没有遇到一个场景,我需要让我的应用程序为线程创建一个新的公寓,所以一些洞察力将有助于更好地理解线程模型。 更新:在阅读了更多关于公寓和COM之后,它开始有所了解。 现在我想知道.NET托管线程类默认是什么,我们可以以托管的方式为每个线程指定一个没有P / Invoke的公寓模型吗?

互操作后Excel过程仍然保持打开状态; 传统方法不起作用

我遇到了一些我正在调试的代码问题。 Excel interop用于从工作簿中提取某些值; 但是,程序退出后Excel仍保持打开状态。 我已经尝试了传统的解决方案,但它仍然在运行代码的所有机器上保持对Excel的引用 private void TestExcel() { Excel.Application excel = new Excel.Application(); Excel.Workbooks books = excel.Workbooks; Excel.Workbook book = books.Open(“C:\\test.xlsm”); book.Close(); books.Close(); excel.Quit(); Marshal.ReleaseComObject(book); Marshal.ReleaseComObject(books); Marshal.ReleaseComObject(excel); } 即使是这段简单的代码也可以使进程运行多个文件(xlsm,xlsx,xls)。 现在我们有一个解决方法来杀死我们已经打开的Excel进程,但我更愿意让这个工作为我自己的理智。 我应该补充一点,我把它缩小到Workbook变量。 如果我删除对books.Open()的调用以及对book所有引用,则它会成功关闭。

通过C#启动的PowerPoint不会退出

嘿我从C#WinForms应用程序自动化PowerPoint和Excel; 我所做的是从PowerPoint中读取幻灯片并将其保存在Excel中,然后退出这两个应用程序。 Excel退出成功但PowerPoints不退出。 问题是当我第一次转换它不退出时,但当我再次转换时它确实。 这是我的代码 try { PowerPoint.Application ppApp; PowerPoint.Presentation ppPres; List companies = new List(); ppApp = new PowerPoint.Application(); ppApp.Visible = Microsoft.Office.Core.MsoTriState.msoTrue; ppApp.WindowState = Microsoft.Office.Interop.PowerPoint.PpWindowState.ppWindowMinimized; ppPres = ppApp.Presentations.Open(fileTxtBox.Text, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoTrue); int slides = ppPres.Slides.Count; for (int slide = 1; slide <= slides; slide++) { int rows = 1; PowerPoint.Cell cell; int shape = […]

将数组从C#COM对象传递给JavaScript?

与此类似如何将一个字符串数组从ActiveX对象返回到JScript但在C#中。 我有一个COM控件,将一个字符串数组传递给javascript。 似乎javascript无法理解它是什么我传回来并且javascript中的数组总是未定义的。 使用Javascript: try { keystore.openKeyStore(“MY”, true, false); var fNames = new Array(); fNames = keystore.getAllFriendlyNames(); document.getElementById(‘par’).innerHTML = fNames[0]; } catch(err) { document.getElementById(‘err’).innerHTML = err.description; } 这为fNames[0];输出’undefined’ fNames[0]; C#: public object[] getAllFriendlyNames() { if (!keystoreInitialized) throw new Exception(“Key store has not been initialized”); X509Certificate2Collection allCerts = certificateStore.Certificates; int storeSize = allCerts.Count; if (storeSize == […]

将C#COM服务器事件暴露给Delphi客户端应用程序

我的问题与这两个非常相似: C#组件事件? C# – 编写COM服务器 – 未在客户端上触发的事件 然而,对他们有用的不适合我。 类型库文件没有任何事件定义提示,因此Delphi没有看到它。 正如您所料,该类适用于其他C#应用程序。 COM服务器工具: Visual Studio 2010 .NET 4.0 Delphi应用程序: Delphi 2010 delphi7 这是代码的简化版本: /// /// Call has arrived delegate. /// [ComVisible(false)] public delegate void CallArrived(object sender, string callData); /// /// Interface to expose SimpleAgent events to COM /// [ComVisible(true)] [GuidAttribute(“1FFBFF09-3AF0-4F06-998D-7F4B6CB978DD”)] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IAgentEvents { /// /// […]

在不使用COM的情况下从C ++调用C#方法

有没有办法创建C#对象并从非托管C ++调用方法,但没有使用COM Iterop? 我正在寻找像JNI(但对于.Net)这样的东西,你可以手动创建VM,创建对象等。

我是否需要在每个’foreach’迭代中释放COM对象?

这是(潜在的)问题: 我创建一个COM对象,然后使用’foreach’迭代它返回的集合中的每个元素。 我是否需要释放我在集合中迭代的每个元素? (参见下面的代码。)如果是这样,我想不出有效地从’finally’语句中释放它的方法,以防万一在项目被操作时出现错误。 有什么建议? private static void doStuff() { ComObjectClass manager = null; try { manager = new ComObjectClass(); foreach (ComObject item in manager.GetCollectionOfItems()) { Log.Debug(item.Name); releaseComObject(item); // <– Do I need this line? // It isn't in a 'finally' block… // …Possible memory leak? } } catch (Exception) { } finally { releaseComObject(manager); […]

如何在C#中枚举COM对象的成员?

我通过COM连接到某个程序并接收System .__ ComObject。 我知道它的几种方法,所以我可以这样做: object result = obj.GetType().InvokeMember(“SomeMethod”, BindingFlags.InvokeMethod, null, obj, new object[] { “Some string” }); 并且喜欢这个 dynamic dyn = obj; dyn.SomeMethod(“Some string”); 两种方法都很好。 但是如何确定com对象的内部类型信息并通过其所有成员进行枚举? 我试过这个: [ComImport, Guid(“00020400-0000-0000-C000-000000000046”), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDispatch { void Reserved(); [PreserveSig] int GetTypeInfo(uint nInfo, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(TypeToTypeInfoMarshaler))] out System.Type typeInfo); } … IDispatch disp = (IDispatch)obj; […]

致命执行引擎错误(79FFEE24)(80131506)

我遇到了.NET Framework 3.0 SP1应用程序的问题。 它是一个与COM exe通信的C#winforms应用程序。 随机地winforms应用程序或COM exe崩溃没有任何错误消息,事件日志包含此条目: [1958] .NET运行时类型:错误计算机:CWP-OSL029-01时间:11/25/2008 3:14:10 PM ID:1023 .NET运行时版本2.0.50727.1433 – 致命执行引擎错误(79FFEE24)(80131506) 我在MS网站上找不到任何有用的信息。 有没有人知道我应该在哪里开始调查? TIA