我正在实现一个COM接口,它应该返回int值S_OK或E_FAIL.我S_OK可以回复,因为我从另一个调用(Marshal.QueryInterface)得到了回复,但如果我想返回一个失败值,我会使用什么实际值E_FAIL?
(这是一个基本的基本问题,很难找到答案)
假设它是Win32 API中定义的特定数字,是否可以在.net代码中使用它而不声明我自己的常量?
谢谢!
更新(回答如下):
也许我是一个完整的笨蛋,但我遇到了这个问题.根据我的Platform SDK,HRESULT是一个LONG,它是一个32位有符号整数,对吧?所以可能的值-2,147,483,648到2,147,483,647.但是0x80004005 = 2,147,500,037,大于2,147,483,647.是什么赋予了!?
这意味着当我尝试将其放入我的代码中时:
const int E_FAIL = 0x80004005;
Run Code Online (Sandbox Code Playgroud)
我收到编译器错误无法将类型'uint'隐式转换为'int'.
更新2:
我要宣布它是这样的:
const int E_FAIL = -2147467259;
Run Code Online (Sandbox Code Playgroud)
因为如果我尝试做这样的事情:
const UInt32 E_FAIL = 0x80004005;
return (Int32)E_FAIL;
Run Code Online (Sandbox Code Playgroud)
我得到一个编译器错误常量值'2147500037'无法转换为'int'(使用'unchecked'语法来覆盖)
唷!谁知道声明一个标准的返回值是多么棘手....某处必须有一个潜伏的类,我应该使用像返回Win32ReturnCodes.E _FAIL; ...... 叹息
终极解决方案:
我现在通过从pinvoke.net获取(大量但非常有用)HRESULT枚举并将其添加到我的解决方案中来做到这一点.然后使用它像这样:
return HRESULT.S_OK;
Run Code Online (Sandbox Code Playgroud) 我需要使用很久以前在Delphi中开发的COM组件(dll).问题是:dll不包含类型库...并且.NET中的每个互操作功能(例如,TlbImp)似乎都依赖于TLB.这个组件已经在Delphi程序中使用了很多年没有问题,因为"使用Delphi的COM对象并不是什么问题,因为我们知道接口"(引用Delphi开发人员).
有没有办法在没有TLB的情况下从c#中使用这个DLL?我已经使用DLL作为未试过,但唯一的方法是出口DllUnregisterServer,DllRegisterServer,DllCanUnloadNow和DllGetClassObject.我知道我将要使用的类和函数的名称,如果这可以有任何帮助.
更新: 我已经尝试过实施Jeff的建议,但是我收到了这个错误:
"无法将'ComTest.ResSrvDll'类型的COM对象强制转换为接口类型'ComTest.IResSrvDll'.此操作失败,因为对于具有IID'{75400500-939F-11D4-9E44-0050040CE72C}的接口的COM组件上的QueryInterface调用'由于以下错误而失败:不支持此类接口(来自HRESULT的异常:0x80004002(E_NOINTERFACE))."
这就是我所做的:
我从其中一个Delphi人那里得到了这个接口定义:
unit ResSrvDllIf;
interface
type
IResSrvDll = interface
['{75400500-939F-11D4-9E44-0050040CE72C}']
procedure clearAll;
function ResObjOpen(const aClientID: WideString; const aClientSubID: WideString;
const aResFileName: WideString; aResShared: Integer): Integer; {safecall;}
...
end;
implementation
end.
Run Code Online (Sandbox Code Playgroud)
从这个我做了这个界面
using System.Runtime.InteropServices;
namespace ComTest
{
[ComImport]
[Guid("75400500-939F-11D4-9E44-0050040CE72C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IResSrvDll
{
int ResObjOpen(string aClientID, string aClientSubID, string aResFileName, int aResShared);
}
}
Run Code Online (Sandbox Code Playgroud)
而这个coclass(得到了德尔福人的指导)
using System.Runtime.InteropServices;
namespace ComTest
{
[ComImport]
[Guid("75400503-939F-11D4-9E44-0050040CE72C")]
public class ResSrvDll
{
} …Run Code Online (Sandbox Code Playgroud) 我使用VS2008生成了一个ATL COM对象,代码包含对所调用定义的引用_MERGE_PROXYSTUB(因为我在最初运行向导时选择了'Merge proxy/stub'选项.)
代理/存根有什么意义?如果我没有选择合并选项,那么我会得到一个单独的MyControlPS.DLL- 什么时候会被使用?
如果我删除了_MERGE_PROXYSTUB定义包围的所有代码,那么控件似乎注册并正常工作.调试版本甚至没有定义_MERGE_PROXYSTUB,它仍然可以正常工作.
那么,我可以不使用代理/存根吗?
是/RegServer和/RegSvr相同或不同,如果不同为什么/如何?
例如,我见过(32位操作系统的例子)这种风格:
RegSvr32 COM.exe
Run Code Online (Sandbox Code Playgroud)
要么
RegSvr32 COM.dll
Run Code Online (Sandbox Code Playgroud)
或者作为替代方案(在64位操作系统上):
COM.exe /RegServer
COM.exe /RegSvr
Run Code Online (Sandbox Code Playgroud)
这些不同的方法是否做同样的事情?
以下是错误详细信息:
在错误列表中:
错误1无法注册程序集"C:\ Users\cboardman\Documents\Visual Studio 2008\Projects\ExcelAddIn1\ExcelAddIn1\bin\Debug\ExcelAddIn1.dll" - 访问被拒绝.请确保您以管理员身份运行该应用程序.访问注册表项"HKEY_CLASSES_ROOT\ExcelAddIn1 ..."被拒绝.C:\ Windows\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets 3019 9 ExcelAddIn1
在构建输出中:
目标UnmanagedRegistration:C:\ Windows\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(3019,9):错误MSB3216:无法注册程序集"C:\ Users\cboardman\Documents\Visual Studio 2008\Projects\ExcelAddIn1\ExcelAddIn1\bin\Debug\ExcelAddIn1.dll" - 访问被拒绝.请确保您以管理员身份运行该应用程序.访问注册表项"HKEY_CLASSES_ROOT\ExcelAddIn1 ..."被拒绝.在项目"ExcelAddIn1.csproj"中完成构建目标"UnmanagedRegistration" - 失败.
根据我在网上找到的内容,我需要以管理员身份运行Visual Studio.对于小钉子来说,这似乎是一把大锤子.有没有办法解决这个问题(就像以管理员身份运行注册一样)?
wprintf(L"Selecting Audio Input Device: %s\n",
varName.bstrVal);
if(0 == strcmp(varName.bstrVal, "IP Camera [JPEG/MJPEG]"))...
Run Code Online (Sandbox Code Playgroud)
以上报道:
error C2664: 'strcmp' : cannot convert parameter 1 from 'BSTR' to 'const char *'
Run Code Online (Sandbox Code Playgroud) 我一直在使用一些DirectShow接口来使用C#和DirectShow.Net播放数字电视(DVB-T).我最近遇到了运行时错误COM object that has been separated from its underlying RCW cannot be used.
此错误发生在以下行:
_guideData = _transportInformationFilter as IGuideData;
_transportInformationFilter 是IBaseFilter类型,是以前通过DirectShow.Net实用程序函数分配的COM对象.
我认为错误是由于_transportInformationFilter某种程度上过早释放,我跟踪它到以下方法(删除错误处理):
private void AttachGuideDataEvent()
{
IConnectionPoint connPoint = null;
IConnectionPointContainer connPointContainer = null;
try
{
connPointContainer = _transportInformationFilter as IConnectionPointContainer;
if (connPointContainer == null) /* error */
var guideDataEventGuid = typeof (IGuideDataEvent).GUID;
connPointContainer.FindConnectionPoint(ref guideDataEventGuid, out connPoint);
if (connPoint == null) /* error */
int cookie;
connPoint.Advise(this, out cookie);
if (cookie == 0) /* error …Run Code Online (Sandbox Code Playgroud) 从C#使用MSMQManagement的最佳方法是什么?当远程计算机断开连接时,我需要能够查看和清除本地传出队列.
显然,一些用户可以通过COM API执行此操作,但在COM参考选项卡中,我没有其他网站/博客/帖子提到的"Microsoft Message Queue 3.0对象库"(也没有任何类似的东西).我在机器上搜索了Interop.MSMQ.dll,也找不到它.
我们正在使用VS 2008并在Windows 7 64位上运行.
我错过了什么?是否有其他机制通过"普通"托管类来实现这一目标?
谢谢
我们一直在我们的程序中使用旧的msado15.dll.我们曾经导入它#import"msado15.dll".现在几天前我们升级到Windows 8.唉,我们的软件停止在没有安装Service Pack 1的Windows 7上运行.早些时候,当我们使用Windows 7时,我们已升级到Service Pack 1,同样的问题发生了,所以我们从所有机器上卸载了Windows 7的Service Pack 1,一切正常.
但是对于Windows 8,我认为他们已经改变了msado15.dll.我在网上进行了一些研究,他们说我们应该用msado60.tlb替换导入,但这对我们的编译破坏也没有用.
这就是我们过去在C++环境中引用的方式
import "c:\program Files\Common Files\system\ado\msado15.dll" rename_namespace("ADOCG") rename("EOF","EndofFile")
Run Code Online (Sandbox Code Playgroud)
我把它改成了
import "c:\program Files\Common Files\system\ado\msado28.tlb" rename_namespace("ADOCG") rename("EOF","EndofFile")
Run Code Online (Sandbox Code Playgroud)
并尝试过
import "c:\program Files\Common Files\system\ado\msado60.tlb" rename_namespace("ADOCG") rename("EOF","EndofFile")
Run Code Online (Sandbox Code Playgroud)
正如Microsoft Link所建议的那样.但它仍然适用于没有安装Service Pack 1的XP机器和Windows 7机器.
任何人都可以建议我们可以遵循的正确步骤,以使我们的程序在没有Service Pack 1的Windows 7上运行,也可以在Windows 8上运行.
几天来一直坚持这个问题.帮助将不胜感激.
问候,Saurabh
此处描述了在没有管理员权限的情况下调用regasm的解决方法:
我正在尝试创建一个COM库,我的用户可以在没有管理员权限的情况下从Excel VBA部署和使用它.我喜欢regasm解决方法,因为似乎人们在使用Excel VBA中的免注册COM对象方面没有太大成功.我也希望早期绑定,以便我的用户可以从语法完成中受益.
但是,上述问题中接受的答案并未描述将汇编dll放在用户计算机上的位置.管理员权限是在GAC中安装程序集所必需的,所以我想知道在哪里可以放置dll文件.我假设应用程序的目录正在搜索任何引用的dll,但我不能将我的dll放在Excel的目录中而没有管理员权限.是否可以使用Excel客户端的变通方法?有没有其他方法从VBA调用COM对象而不需要管理员权限来首先部署它们?