将项目从.NET 1.1移动到.NET 2.0后,MsBuild会为某些COM对象发出大量警告.
测试的示例代码(实际代码无关紧要,仅用于创建警告):
using System;
using System.DirectoryServices;
using ActiveDs;
namespace Test
{
public class Class1
{
public static void Main(string[] args)
{
string adsPath = String.Format("WinNT://{0}/{1}", args[0], args[1]);
DirectoryEntry localuser = new DirectoryEntry(adsPath);
IADsUser pUser = (IADsUser) localuser.NativeObject;
Console.WriteLine("User = {0}", pUser.ADsPath);
}
}
}
Run Code Online (Sandbox Code Playgroud)
警告消息看起来像
C:\ WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets:警告:运行时封送程序无法对"ITypeLib.RemoteGetLibAttr"的至少一个参数进行封送处理.因此,这些参数将作为指针传递,并且可能需要操作不安全的代码.
观察:
<Reference>
.csproj文件中的条目包含属性 WrapperTool = "tlbimp"
知道怎么摆脱警告吗?
我的一位同事在VB.net中创建了一个程序集,用于通过COM互操作与JScript一起使用.组件过去工作正常,但我们签了它,现在它似乎只适用于Windows 7机器.我测试了2台Windows 7机器和2台Windows Vista机器.
当我们签署程序集并尝试在JScript中实例化ActiveX对象时,将返回一个错误,但没有消息,只有一个数字:
错误:
错误号:-2146234304
在Google上搜索错误编号并没有太多回复.
如果我们从程序集中删除强名称,它就可以正常工作.关于什么可能是问题的任何想法?不确定它是否有所作为,但正在使用VS 2010编译和签署程序集.
创建一个COM服务器,然后我注册了它.
当我试图在COM客户端中添加该COM服务器时,我无法添加,并且出现以下错误.
"无法添加对'COMTest'的引用
ActiveX类型库'c\user \〜\ Debug\COMTest.tlb'是从.NET程序集导出的,无法添加为引用.
添加对.NET的引用"
任何人都可以告诉我这是什么错误.我以两种方式注册COM,也来自VS,也尝试使用命令提示符.
我有一个.NET程序集,我通过tlb文件向COM公开,以及一个注册tlb的安装程序.我已手动检查安装程序是否正常工作,并且COM客户端可以访问该库.到现在为止还挺好...
但是,我正在尝试组合一些自动系统测试,检查安装程序是否正常工作.作为其中的一部分,我已经在VM上自动安装,我现在想要对已安装的COM库进行一些调用以验证它是否正常工作.我最初想过在VB6中编写一些测试,但我已经有了一大堆用C#编写的测试,它引用了.NET程序集.我希望我可以更改这些以引用.tlb,但是当我在VS2008中尝试这个时出现错误:
ActiveX类型库'blah.tlb'是从.NET程序集导出的,无法添加为引用.
有什么方法可以欺骗VS2008允许我添加这个引用,也许是通过编辑tlb文件?
谷歌搜索没有提出任何解决方案.我发现的只是一篇Microsoft Connect文章,声明这是"按设计":http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx ?FeedbackID = 120882
使用VS 2008,这是我的COM对象
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace TestCom
{
[Guid("9E5E5FB2-219D-4ee7-AB27-E4DBED8E123E")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("Test9.COMINT")]
public class TestComClass
{
public void Init(string userid, string password)
{
MessageBox.Show(string.Format("{0}/{1}", userid, password));
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我构建它并在生产机器上注册如下
REGASM /CODEBASE TESTCOM.DLL
Run Code Online (Sandbox Code Playgroud)
从一个简单的VB6应用程序,这工作正常
Private Sub Form_Load()
Dim o As Object
Set o = CreateObject("Test9.COMINT")
o.Init "A", "B"
End Sub
Run Code Online (Sandbox Code Playgroud)
这个完全相同的代码从Excel中的VBA调用
"自动化错误"(0x80131700)
一切都在开发机器上运行良好,而不是只安装了.NET和MS Office的生产机器上.
我认为这与.NET框架在Excel下运行时未正确初始化有关.如果我使用Filemon,我可以看到它跳过寻找MSCORWKS.DLL.当我从VBScript调用相同的对象时,它发现MSCorwks.dll很好.
当我打电话CorBindToCurrentRunTime
从VBA,试图强行加载CLR,有趣的是我得到确切同样的HRESULT (0x80131700)
,当我做CreateObject()
在VBA.
因此我认为这是一个框架初始化问题.
我创建了一个ASP.NET Web服务,它使用第三方支付处理引擎来授权信用卡交易.
Web服务托管在单独的应用程序服务器上,并通过ActiveX对象(.ocx
扩展名)连接到支付处理服务器.最近,HRESULT: 0x80010105 (RPC_E_SERVERFAULT)
当我尝试使用" IsAvaiable
"检查建立与应用程序的连接时,它一直在生成异常.
有没有人建议开始研究这个问题的好地方?
(我知道联系供应商将是第一个选择,但我想在联系技术支持之前让我的"鸭子连续")
根据这篇文章,如果我用"Both"或"Free"线程模型注册我的COM对象,该对象必须完全是线程安全的.具体而言,必须同步对全局共享变量的所有访问,并且还必须同步对成员变量的所有访问.这是很多努力.
现在我明白能够将我的对象注册为使用"Free"线程模型是有利的,并且可能值得付出使其完全线程安全的代价.但是为什么我要做所有相同的操作并使用"Both"线程模型注册我的对象呢?有什么好处?如何选择"两者"和"免费"?
所有这些问题:
解决了C#在使用后没有正确释放Excel COM对象的问题.解决这个问题主要有两个方向:
有人说过2太繁琐了,你是否忘记在代码中的某些地方忘记遵守这条规则总是存在一些不确定性.仍然1对我来说似乎很脏并且容易出错,我想在有限的环境中试图杀死一个进程可能会引发安全错误.
所以我一直在考虑通过创建另一个模仿Excel对象模型的代理对象模型来解决问题2(对我来说,实现我实际需要的对象就足够了).原则如下:
例:
public class Application
{
private Microsoft.Office.Interop.Excel.Application innerApplication
= new Microsoft.Office.Interop.Excel.Application innerApplication();
~Application()
{
Marshal.ReleaseCOMObject(innerApplication);
innerApplication = null;
}
public Workbooks Workbooks
{
get { return new Workbooks(innerApplication.Workbooks); }
}
}
public class Workbooks
{
private Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks;
Workbooks(Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks)
{
this.innerWorkbooks = innerWorkbooks;
}
~Workbooks()
{
Marshal.ReleaseCOMObject(innerWorkbooks);
innerWorkbooks = null;
}
}
Run Code Online (Sandbox Code Playgroud)
我特别向你提问:
此处描述了在没有管理员权限的情况下调用regasm的解决方法:
我正在尝试创建一个COM库,我的用户可以在没有管理员权限的情况下从Excel VBA部署和使用它.我喜欢regasm解决方法,因为似乎人们在使用Excel VBA中的免注册COM对象方面没有太大成功.我也希望早期绑定,以便我的用户可以从语法完成中受益.
但是,上述问题中接受的答案并未描述将汇编dll放在用户计算机上的位置.管理员权限是在GAC中安装程序集所必需的,所以我想知道在哪里可以放置dll文件.我假设应用程序的目录正在搜索任何引用的dll,但我不能将我的dll放在Excel的目录中而没有管理员权限.是否可以使用Excel客户端的变通方法?有没有其他方法从VBA调用COM对象而不需要管理员权限来首先部署它们?
我们有一个.NET应用程序,它使用不同DLL中的COM对象,也用于我们应用程序的VB6部分.在引用COM库时,Visual Studio 2012会创建一个Interop.x.DLL并引用它.我应该从构建计算机分发Interop.x.DLL还是使用某些.NET命令行工具重新生成它?什么工具?部署引用COM的.NET应用程序的最佳实践是什么?
com-interop ×10
.net ×5
c# ×5
com ×5
interop ×3
vba ×2
assemblies ×1
deployment ×1
excel ×1
excel-vba ×1
javascript ×1
msbuild ×1
regasm ×1
strongname ×1
tlbimp ×1
vb6 ×1
web-services ×1
windows ×1