我遇到了经典场景,当在.NET中创建Word COM对象时(通过Microsoft.Office.Interop.Word程序集),即使我正确关闭并释放对象,WinWord进程也不会退出.
我已经将其缩小到使用Word.Documents.Add()方法.我可以在没有问题的情况下以其他方式使用Word(打开文档,修改内容等),并在我告诉它时退出WinWord.exe.一旦我使用Add()方法(并且仅在添加模板时),该过程就会继续运行.
这是一个简单的例子,它可以重现这个问题:
Dim word As New Word.Application()
word.Visible = False
Dim documents As Word.Documents = word.Documents
Dim doc As Word.Document = documents.Add(Template:=CObj(templatePath), NewTemplate:=False, DocumentType:=Word.WdNewDocumentType.wdNewBlankDocument, Visible:=False)
'' dispose objects
doc.Close()
While (Marshal.ReleaseComObject(doc) <> 0)
End While
doc = Nothing
While (Marshal.ReleaseComObject(documents) <> 0)
End While
documents = Nothing
word.Quit()
While (Marshal.ReleaseComObject(word) <> 0)
End While
word = Nothing
GC.Collect()
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在创建和正确处理对象,甚至采取额外的步骤来循环Marsha.ReleaseComObject,直到它返回正确的代码.在其他方面使用Word对象很好,只是那些讨厌的Documents.Add让我感到悲伤.是否有另一个在此过程中创建的对象需要引用和处理?我需要遵循另一个处理步骤吗?别的什么?非常感谢您的帮助 :)
Update: 我在处理步骤结束时尝试了GC.Collect,但仍然没有运气.
Update 2: 我已经将问题缩小到使用自定义模板.当我调用Documents.Add(...)时,我为新文档指定了一个自定义模板.如果我不这样做而是调用没有参数的Add(),那么问题就不会发生.
我总是将我的.NET程序集标记为COM可见[assembly: ComVisible(true)],以为我从来不知道有人可能需要从COM调用它们.我也开始使用FxCop并开始从代码分析中看到这个警告:
CA1017:Microsoft.Design:因为"MyLibrary.dll"公开了外部可见类型,所以在程序集级别使用ComVisible(false)标记它,然后使用ComVisible标记应该向COM客户端公开的程序集中的所有类型(true)
是否有一些理由让您不希望所有公共类型都暴露给COM?我猜这有,但我无法想象这是什么原因.如果有的话,它似乎非常不方便.
这是我的代码,我找到了许多VBA,.NET框架的答案,并且非常奇怪.执行此操作时,Excel将关闭.
from win32com.client import DispatchEx
excel = DispatchEx('Excel.Application')
wbs = excel.Workbooks
wbs.Close()
excel.Quit()
wbs = None
excel = None # <-- Excel Closes here
Run Code Online (Sandbox Code Playgroud)
但是,当我执行以下操作时,它不会关闭.
excel = DispatchEx('Excel.Application')
wbs = excel.Workbooks
wb = wbs.Open('D:\\Xaguar\\A1.xlsm')
wb.Close(False)
wbs.Close()
excel.Quit()
wb = None
wbs = None
excel = None # <-- NOT Closing !!!
Run Code Online (Sandbox Code Playgroud)
我在Stack Overflow问题中找到了一些可能的答案.传统方法不起作用.问题是不是Python,我找不到Marshal.ReleaseComObject和GC.我查看了所有演示...site-packages/win32com和其他演示.
如果我能获得PID并杀死它,即使它也不会打扰我.
我在Kill进程中找到了一个基于窗口名称(win32)的解决方法.
可能不是正确的方法,但是工作环境是:
def close_excel_by_force(excel):
import win32process
import win32gui
import win32api
import win32con …Run Code Online (Sandbox Code Playgroud) 我遇到了.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
谁能解释上面提到的类型和一些样本用法之间的区别,以清楚地解释两者之间的区别?
任何帮助将非常感谢!注意:这个问题是另一个问题的副产品
如何通过COM4J从C#方法返回一个对象数组(实现COM接口)到Java方法?
示例C#生成数组的类:
using System;
using System.Runtime.InteropServices;
namespace Example
{
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAnimal
{
string Speak();
}
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFarm
{
[return:MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType=VarEnum.VT_UNKNOWN)]
IAnimal[] GetAnimals();
}
[ComVisible(true), ClassInterface(ClassInterfaceType.None)]
public class Farm : IFarm
{
public IAnimal[] GetAnimals()
{
return new IAnimal[] { new Cow(), new Pig() };
}
}
internal class Cow: IAnimal
{
public string Speak()
{
return "Moo";
}
}
internal class Pig: IAnimal
{
public string Speak()
{
return "Oink";
}
}
}
Run Code Online (Sandbox Code Playgroud)
生成的.tlb中的接口声明如下所示: …
我正在为metro应用程序进行自动化测试,我发现代码可以完成我需要的很多东西,但是它是用C++编写的:http://blogs.msdn.com/b/windowsappdev/archive/2012/09/04/自动化最测试-的-窗口8 apps.aspx
我的问题是,如何在C#中使用IApplicationActivationManager :: ActivateApplication,因为我不懂C++?该方法的详细信息可在此处找到:http://msdn.microsoft.com/en-us/library/windows/desktop/hh706903(v = vs.85).aspx
这是我从Shobjidl.idl中提取的代码:
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(ACTIVATEOPTIONS)")
// IApplicationActivationManger is used to activate an immersive application identified by its Application User Model Id.
//
// Developers who are interested in using the Application Activation Manager do not need to implement the following
// interface. An implementation is provided through the CoCreatable Object with CLSID_ApplicationActivationManager.
[
object,
uuid(2e941141-7f97-4756-ba1d-9decde894a3d),
pointer_default(unique)
]
interface IApplicationActivationManager : IUnknown
{
// Activates the specified immersive application for the …Run Code Online (Sandbox Code Playgroud) 我必须从头开始重新实现现有系统.
有一次,当用户导航到某个网页时,服务器必须从用户的串口读取数据.
目前,该网页具有ActiveX控件; 当页面加载时,ActiveX控件调用用户PC上的COM DLL,该DLL从串行端口读取数据.
该系统已有10年历史.有没有"更好"的方式可以实现这个?
例如,技术在过去十年中不断发展.而这个解决方案似乎只适用于MS IE,它现在的市场份额约为26%(2013年,当我上次更新这个问题时.截至2107年2月,MS IE有3-4%而且Edge有由于Edge也是MS产品,它可能支持Active X - 我没有尝试过.Otoh,因为它是从头开始的新功能,很有可能它没有.)
HTML 5是否提供了任何新的可能性?Cordova等产品怎么样?
还有其他可能性吗?
我可以添加一个Raspberry Pi来通过串口读取吗?并让浏览器应用程序通过RESTful服务与之通信?
[更新] @ EuroMicelli说:"我将假设您有充分的理由从网络浏览器而不是本机应用程序运行您的应用程序".我不知道原来的项目计划时我不在身边(设计它的公司现在已经不存在了).
也许他们不希望最终用户直接与数据库连接?也许"基于浏览器"当时是一个新的流行语?我个人对桌面应用程序没有任何问题(因为我发现它们更容易实现),但是我们应该考虑保留基于浏览器的?(此外,我可以自己处理桌面应用程序;它只是从COM端口读取浏览器,导致我提供奖金;-)
我使用ATL(VS2008,所以ATL9 IIRC)来创建COM对象,并一直使用CComVariant类(定义atlcomcli.h)来管理VARIANT类型.但是,还有一个VARIANT名为的包装器_variant_t.是否有任何区别CComVariant,并_variant_t和我应该使用哪一个?
同样,有两个BSTR包装器 - CComBSTR和_bstr_t.再说一次,我应该选择哪个?为什么?
我在php中调用COM类中的任何方法都遇到了麻烦.为了找到该类中的所有方法,我使用了:
$com = new COM('Some.Class.Name');
com_print_typeinfo($com);
Run Code Online (Sandbox Code Playgroud)
这个类包含了100种不同的方法.但是当他们打电话时:
$com->SomeMethod();
Run Code Online (Sandbox Code Playgroud)
,弹出这个错误:
致命错误:在第22行的C:\ xampp\htdocs\www\test.php中调用未定义的方法com :: SomeMethod()
当我使用其他COM对象(如" InternetExplorer.Application "类)时,不会发生这种情况.另外,我知道这个COM对象与Delphi等其他编程语言一样可以正常工作.
我在64位Windows Vista上使用PHP 5.5.19,在32位PHP架构上使用XAMPP.
对于这种情况可能发生的事情或一些可能的解决方法,我将不胜感激.
编辑: COM服务器应用程序是用Delphi编写的.
这可能是另一个线索:当我使用代码时
$com = new COM('Some.Class.Name');
foreach ($com as $obj) {
echo $obj->Name . "<br />";
}
Run Code Online (Sandbox Code Playgroud)
我明白了:
致命错误:未捕获的异常'异常',消息'类型为com的对象未创建迭代器'
我想这表明应用程序界面本身可能存在问题,但我不知道该问题可能是什么.我在PHP中工作,所以COM对象的内部对我来说是完全模糊的.但我非常感谢有关具体步骤的任何线索,以解决这种情况.
EDIT2: 这是Srv_TLB.pas文件的简短代码.
unit Srv_TLB;
{$TYPEDADDRESS OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface
uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;
const
// TypeLibrary Major and minor versions
SrvMajorVersion = 1;
SrvMinorVersion = 0;
LIBID_Srv: …Run Code Online (Sandbox Code Playgroud)