标签: com

如何在没有消息的情况下等待WaitHandle?

我想WaitHandle.WaitOne(TimeSpan)在.NET中调用,但我在STA线程上,它在等待时抽取消息.由于超出此问题范围的原因,我需要等待而不需要抽水.如何在不抽取消息的情况下等待WaitHandle发出信号?

在某些情况下WaitHandle.WaitOne似乎不会消息.但它有时会发生一些消息.有关详细信息,请参阅以下链接:

  1. Microsoft Windows中的托管和非托管线程
  2. 管理阻塞

.net com multithreading

10
推荐指数
1
解决办法
3019
查看次数

通过.NET调用COM对象的手动方式

是否有手动方式在.NET中调用GAC中的COM对象,而不将其添加为引用?

我问的原因是我只知道如何在C#中编码并想要调用.NET COM对象并测试其CMO调用是否可见,但显然您无法将.NET COM对象添加到.NET程序集中!因为你必须引用它,所以我想知道如果它通过c#代码手动在GAC中注册,你可以调用它吗?

c# com com-interop

10
推荐指数
1
解决办法
5475
查看次数

C# - 将Nullable <T>暴露给COM的好方法

我们正在努力将程序集暴露给COM.

除此之外,我们频率使用可空值,例如long?,DateTime?等.这些是泛型类型,不能暴露给COM.

什么是COM的这些数据类型的良好替代品?

我们尝试过以下方法:

//Original CustomerID property in class
public long? CustomerID
{
   get;
   set;
}

//Explicit COM interface
long IComInterface.CustomerID
{
  get { return CustomerID.GetValueOrDefault(); }
  set { CustomerID = value; }
}
Run Code Online (Sandbox Code Playgroud)

问题是,我们需要一种通过COM来回传递"null"的方法.使用-1或0之类的数字将不起作用,因为它们也是有效值.

我们不得不使用nullables b/c这些最初来自我们的数据库模式.

.net c# com nullable

10
推荐指数
1
解决办法
1282
查看次数

当用户注销时,Excel COM自动化停止工作

我开发了一个服务器应用程序,它使用Excel 2007 COM自动化来转换一些xls文件.它作为Windows Datacenter实例上的服务启动,在其自己的用户下运行,我不得不更改DCOM安全设置("作为交互式用户启动")以使其工作.

问题是,当我注销(通过RDP)时,它会停止工作.我登录,它再次工作.

有没有人有同样的问题?我很高兴在这一点上有任何帮助.

com excel automation dcom

10
推荐指数
3
解决办法
1万
查看次数

如何强制python(使用win32com)创建一个新的excel实例?

我正在自动执行一些需要很长时间的excel相关任务.

我正在使用以下方法创建一个excel实例:

excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Add()
Run Code Online (Sandbox Code Playgroud)

但是,在脚本开始运行之后,如果我选择一个打开的excel工作簿(而不是一个python正在处理),那么python脚本会崩溃.但是,如果我打开一个新的excel工作簿并在其中键入内容,python脚本不受影响.

有没有一种特殊的方式我可以调用excel来防止这种情况发生?或任何其他解决方案?

编辑:这似乎工作.

excel = win32.DispatchEx('Excel.Application')
Run Code Online (Sandbox Code Playgroud)

python com excel

10
推荐指数
2
解决办法
4282
查看次数

COM与非COM DLL

我的大部分经验是使用Java和VB.NET等高级语言.我确实有一些C++经验(在大学).

我理解COM DLL和.NET编译器生成的DLL之间的区别.我不完全理解COM DLL和C和C++编译器生成的Windows DLL之间的区别.

我想在.NET程序中使用C++ DLL.我设法让这个工作.我的问题具体是:C++生成的DLL和VB6生成的DLL(基于COM)之间有什么区别.

我花了一个小时谷歌搜索并查看MSDN.我虽然能在不问问题的情况下找到答案,但我没有.

vb.net com dll

10
推荐指数
2
解决办法
3433
查看次数

在OLE Word自动化中搜索和替换 - 如何覆盖页眉和页脚?

我有一个完美的工作函数来查找和替换word文档中的文本变量.

HRESULT CMSWord::FindReplace( CString szVar, CString szText, bool bOnlyOnce/*=false*/ )
{
    if(m_pWApp==NULL || m_pActiveDocument==NULL) return E_FAIL;
    IDispatch *pDocApp;
    {  
        VARIANT result;
        VariantInit(&result);
        OLEMethod(DISPATCH_PROPERTYGET, &result, m_pActiveDocument, L"Application", 0);
        pDocApp= result.pdispVal;
    }
    IDispatch *pSelection;
    {
        VARIANT result;
        VariantInit(&result);
        OLEMethod(DISPATCH_PROPERTYGET, &result, pDocApp, L"Selection", 0);
        pSelection=result.pdispVal;
    }
    IDispatch *pFind;
    {
        VARIANT result;
        VariantInit(&result);
        OLEMethod(DISPATCH_PROPERTYGET, &result, pSelection, L"Find", 0);
        pFind=result.pdispVal;
    }
    OLEMethod(DISPATCH_METHOD, NULL, pFind, L"ClearFormatting",0);

    szText.Replace(_T("\r\n"), _T("\v")); 
    COleVariant sVariable(szVar);
    COleVariant sReplaceText(szText);
    COleVariant replace((long)2);
    COleVariant varBoolTrue;
    varBoolTrue.boolVal = true;
    COleVariant varBoolFalse;
    varBoolFalse.boolVal = false;
    COleVariant wdContinue((long)1); …
Run Code Online (Sandbox Code Playgroud)

com mfc ole office-automation visual-c++

10
推荐指数
1
解决办法
1675
查看次数

Regfree COM事件从其他线程失败

我有一个COM可见的.NET类,它暴露事件并从VB6使用.在过去的几天里,我一直试图让这个与regfree COM一起工作,但没有成功.

  • 当从原始线程触发事件时,VB6事件以regfree模式运行.
  • 当注册了类型库时,VB6事件在从另一个线程触发时运行.(regasm/tlb/codebase后跟regasm/codebase/unregister,后者不注销tlb)

在regfree模式下从另一个线程触发时,它会抛出异常,因此永远不会执行VB6事件代码.

System.Reflection.TargetException: Object does not match target type.

   at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
   at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
   at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
   at Example.Vb6RegFreeCom.IExampleClassEvents.TestEvent()
   at Example.Vb6RegFreeCom.ExampleClass.OnTestEvent(Action func) in ExampleClass.cs:line 78
Run Code Online (Sandbox Code Playgroud)

我可以想到两种情况:1)清单缺少与tlb注册相关的内容,或者2)创建新线程时激活上下文丢失.不幸的是,我不知道如何找出是哪种情况,或者甚至可能是由其他东西引起的.

以下是显示我的问题的基本示例.

清单(VB6可执行文件)

<?xml version="1.0" encoding="utf-8"?>
<assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <assemblyIdentity name="VB6COM" …
Run Code Online (Sandbox Code Playgroud)

.net c# vb6 com regfreecom

10
推荐指数
1
解决办法
1137
查看次数

接口版本控制

在我工作的地方,我们刚刚发布了一个使用dll的功能,该功能严重依赖于接口.dll和所有客户端应用程序都是用Delphi编写的.无需注册.这个DLL不是一个合适的com服务器.唯一的限制是dll和客户端应用程序都可以访问包含接口的单元.这允许我们将复杂数据传递给使用此dll的应用程序,而不需要求助于记录指针,数组或极其繁重的函数签名,也不需要bpl或完全兼容的COM服务器引入的包袱.

看起来它解决了我们遇到的一个没有缺点的重大问题.不幸的是有一个缺点.接口发布后对接口的任何更改都需要随后重新编译该接口的任何使用者.这对于属于同一发布周期的项目来说很好,但是我们的一些项目有不同的发布计划.

我对此进行了一些研究,看起来通常的做法是引入一个继承自之前发布的接口的新接口,而不是修改原始接口.

type
  IOriginalInterface = interface
  ['{8B598EC1-AD92-4144-A1BE-9062C5EA0748}']
    procedure DoSomething;
  end;

  INewInterface = interface(IOriginalInterface)
  ['{DD9D9DE0-0F87-4BC5-803C-74C8AB0F3E39}']
    procedure DoSomethingElse;
  end;
Run Code Online (Sandbox Code Playgroud)

这可确保针对原始接口编译的旧可执行文件继续有效.

我注意到使用RAD Studio打开工具api时,只要引入了新的接口,就会重命名接口.因此,不是为最新的界面提供新名称,而是最新的界面获取原始界面的名称,并重命名原始界面.

type
  IOldInterface = interface
  ['{8B598EC1-AD92-4144-A1BE-9062C5EA0748}']
    procedure DoSomething;
  end;

  IOriginalInterface = interface(IOldInterface)
  ['{DD9D9DE0-0F87-4BC5-803C-74C8AB0F3E39}']
    procedure DoSomethingElse;
  end;
Run Code Online (Sandbox Code Playgroud)

这显然适用于RAD Studio团队以及第三方扩展供应商.这可确保任何重新编译的客户端都将使用最新的接口,而无需更改任何代码.我认为这是有效的,因为名称是无关紧要的,并且在编译代码之后剩下的只是接口定义,使用GUID解析.

说了这么多,这是我们现在面临的界面版本问题的一个很好的解决方案吗?还有其他问题需要注意吗?

delphi com dll interface version

10
推荐指数
1
解决办法
251
查看次数

如何以编程方式启用/禁用"在浏览器中显示PDF"以用于Acrobat/Reader XI或DC以用于Adobe ActiveX控件

我们有一个.NET C#应用程序,它使用Adobe ActiveX控件.对于Adobe Acrobat和Adobe Reader的版本7-10,要使用此控件,您需要打开"在浏览器中显示PDF"设置.您可以使用GUI从GUI手动执行此操作

Preferences > Internet > Display PDFs in browser
Run Code Online (Sandbox Code Playgroud)

或通过直接设置注册表设置以编程方式

HKEY_CURRENT_USER\Software\Adobe\(Product Name)\(Version)\Originals
"bBrowserIntegration"=dword:00000001
Run Code Online (Sandbox Code Playgroud)

其中包含SDK参考http://www.adobe.com/devnet-docs/acrobatetk/tools/PrefRef/Windows/Originals.html#BrowserIntegration.当我们的客户拥有Adobe Reader或Adobe Acrobat的7-10版本时,我们的应用程序一直在以编程方式设置此注册表值.上面的链接还表明bBrowserIntegration在XI(11)中不推荐使用此注册表项.旧版注册表路径仍然存在于新版本中,即:

HKEY_CURRENT_USER\Software\Adobe\(Product Name)\(Version)\Originals
Run Code Online (Sandbox Code Playgroud)

但是,bBrowserIntegration正如文档所示,不再有密钥,它已被弃用.

只要启用了"在浏览器中显示PDF",Adobe ActiveX Control似乎仍可以正常工作,就像它一直有效一样.

对于版本XI(11)和DC,有两个已发布的链接,清楚地显示如何手动实现此目的:

XI (11): https://helpx.adobe.com/acrobat/11/using/display-pdf-browser-acrobat-xi.html
DC (current): https://helpx.adobe.com/acrobat/using/display-pdf-in-browser.html
Run Code Online (Sandbox Code Playgroud)

在测试Adobe Reader DC时,如果我们没有完成在浏览器中为新客户安装启用显示PDF的步骤,那么我们的应用程序将抛出一个COM error,然后如果我们按照上面链接中的说明启用设置,一切正常正如我们的应用程序预期的那样,它使用Adobe ActiveX控件呈现PDF,这与我们期望在未设置注册表设置时在旧版本(7-10)中看到的类似(请参阅我之前的旧帖子和我自己的解决方案)如何逐步诊断原因,修复或解决与Adobe ActiveX/COM相关的错误0x80004005?).

因此,问题仍然是,通过相应地设置注册表设置bBrowserIntegration,对于今天的XI或DC中的手动过程或等同于7-10中的手动过程,预期的程序等效是什么.我们希望能够打开它,然后在我们的应用程序结束时将其重置为之前的设置(因此我们的应用程序不会因为我们的应用程序需要而强制用户保留设置)这就是我们今天所做的7 -10.

我似乎无法在线找到任何从开发人员角度启用/禁用浏览器集成的参考资料,因此我们的应用程序可以继续使用ActiveX控件而不会显示COM错误,从而强制用户手动更改此错误.

首要任务是了解DC的解决方案,因为这代表了Adobe Acrobat/Reader的新范例.

.net pdf com adobe activex

10
推荐指数
1
解决办法
1万
查看次数