我目前正在研究ac #project,我需要访问Outlook.开发工作是在两台不同的机器上完成的,其中一台机器安装了办公室,另一台则没有.我之前曾询问如何针对outlook com对象编译我的项目,其中一条评论建议我针对办公室主互操作程序集或PIA进行编译.在我下载的Office 2007 PIA中,有一个msi文件,应该为Office的不同部分安装许多PIA.我的问题是,这似乎不会发生.打字后,在我办公室的机器上
msiexec /i o2007pia.msi
Run Code Online (Sandbox Code Playgroud)
在提示符下,Windows安装程序启动,并显示一个消息框,显示"请等待Windows配置Microsoft Office 2007主互操作程序集.收集所需信息"以及大约33%的进度条,之后它将消失,之后
gacutil -l microsoft.office.interop.outlook
Run Code Online (Sandbox Code Playgroud)
Office 2007没有产生任何结果(我得到一个结果,版本为10.0.4504.0,是早期安装尝试与Office版本错误的结果.但Office 2007 PIA具有主要版本12.)
我看到了几个可能的解释,其中没有一个我真的相信:
GAC无法处理同一程序集的多个版本,因此不允许我安装较新版本.
不知怎的,我不满足要求.这些基本上都是XPsp2,以及.Net 1.1或更高版本,我都有.要求部分还提到,下载适用于Office 2007,我没有安装,但我不认为这是一个要求.这既是因为没有被指定为要求,而且因为Hans Passant对我原来的问题的评论非常肯定PIA可以专门用于没有安装Office的开发,所以没有任何意义办公室作为先决条件.
那么有没有人知道为什么Office 2007 PIA没有正确安装,或者我能做些什么来接近答案?如果您需要更多信息,请告诉我.谢谢.
我正在尝试遍历各种项目中分散的COM互操作定义的混乱,并将它们收集到一个已知良好的位置,整个开发团队可以从中受益.这项工作的一部分涉及清理多年来积累的定义.
其中一些是从其他源代码借来的,有些是从pinvoke.net逐字复制的,有些看起来是直接从SDK头文件中翻译过来的.我注意到的一件事是关于何时使用各种编组属性没有一致性(即使在pinvoke.net示例中,这也非常棒).部分问题是,我不认为这里的任何人(包括我自己)完全理解何时需要各种属性,或者他们实际做了什么.到目前为止,获得这些权利似乎是猜测和随机变化的结合,直到COMExceptions停止发生,但我更倾向于翻译是正确的,因为有人实际上看了他们并宣布他们如此.
所以,我开始[In]和[Out].我知道这两个属性在概念上是什么:它们告诉编组人员数据必须走向哪个方向.例如,我假设 marshaller不会打扰将[In]数据复制回调用者,或者知道[Out]可能需要在被调用者端释放数据,等等.我不知道的事情是:
[In]是坏的,但是标记输入参数[In, Out]实际上会破坏任何东西?因此,给定一个假设的COM接口方法,其IDL如下所示:
HRESULT Foo(
[in] ULONG a,
[out] ULONG * b
[in, out] ULONG * c);
Run Code Online (Sandbox Code Playgroud)
我可能会将此翻译为以下任何一种:
void Foo(
uint cb,
out uint b,
ref uint c);
void Foo(
uint cb,
[Out] out uint b,
[In, Out] ref uint c);
void Foo(
[In] uint cb,
[Out] out uint b,
[In, Out] ref uint c); …Run Code Online (Sandbox Code Playgroud) 我有一个引用VB6 DLL的C#应用程序.当我将C#中的null传递给VB6 dll函数时,null在VB6中被转换为值Empty(value),而不是Nothing(object).例如:
// function in vb6 dll that referenced by c# app
Public Sub TestFunc(ByVal oValue As Variant)
{
...
if oValue is Nothing then
set oValue = someObject
end if
...
}
// main c# code
private void Form1_Load(object sender, EventArgs e)
{
object testObject = new object();
testObject = null;
TestFunc(testObject);
}
Run Code Online (Sandbox Code Playgroud)
当我传递一个对象(非null)时,它将作为对象传递给VB6.但是当null传递给vb6时,它变为值类型为Empty,而不是对象类型Nothing.谁知道为什么?无论如何,当从c#app传递时,我可以强制null为VB6中的Nothing吗?
非常感谢.
手动注册COM Interop的托管类时,需要某些注册表项.例如
HKEY_CLASSES_ROOT
CLSID\[My Cls Id]
InprocServer32
(Default) = "mscoree.dll"
Assembly = [My assembly name]
etc.
Run Code Online (Sandbox Code Playgroud)
我注意到当VS为COM Interop注册一个库时,它还会添加一个键
HKEY_CLASSES_ROOT
CLSID\[My Cls Id]
Implemented Categories
{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}
Run Code Online (Sandbox Code Playgroud)
这个关键是什么,是否绝对必要?据我所知,如果没有它,生活就会好起来,但也许我没有遇到需要它的情况.
这是(潜在的)问题:
我创建一个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);
}
}
private static void releaseComObject(object instance)
{
if (instance != null)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(instance);
}
catch
{
/* log potential memory leak */
Log.Debug("Potential memory …Run Code Online (Sandbox Code Playgroud) 我正在C#(.NET 4.0)中构建一个COM对象,用于经典的asp站点.现在我想知道在组件和asp站点之间来回编组VB脚本数组(单维和多维)的正确方法是什么?代码示例将受到高度赞赏.
以下vbscript代码完美地工作:
Dim App
Set App = GetObject("","QuickTest.Application")
App.Quit
Run Code Online (Sandbox Code Playgroud)
但是当我将它翻译成C#代码时,如下所示:
class Program
{
[STAThread]
static void Main(string[] args)
{
object qtApp = Marshal.GetActiveObject("QuickTest.Application");
(qtApp as QuickTest.Application).Quit();
}
}
Run Code Online (Sandbox Code Playgroud)
我得到了例外:
mscorlib.dll中发生未处理的"System.Runtime.InteropServices.COMException"类型异常
附加信息:( HRESULT异常:0x800401E3(MK_E_UNAVAILABLE))
我不认为问题与ROT有关,因为vbscript代码有效.那么C#代码有什么问题?
使用COM对象考虑以下C#代码.
MyComObject o = new MyComObject;
try
{
var baz = o.Foo.Bar.Baz;
try
{
// do something with baz
}
finally
{
Marshal.ReleaseComObject(baz);
}
}
finally
{
Marshal.ReleaseComObject(o);
}
这将释放COM对象o和baz,而不是临时对象returnd的o.Foo和o.Foo.Bar.当这些对象拥有大量非托管内存或其他资源时,这可能会导致问题.
一个明显但丑陋的解决方案是,使用try-finally和更加混乱代码Marshal.ReleaseComObject.请参阅
C#+ COM Interop,确定性版本
作为一种解决方法,我创建了一个帮助类
class TemporaryComObjects: IDisposable
{
public C T<C>(C comObject)
{
m_objects.Add(comObject);
return comObject;
}
public void Dispose()
{
foreach (object o in m_objects)
Marshal.ReleaseComObject(o);
}
}
用法:
using (TemporaryComObjects t = new TemporaryComObjects())
{ …Run Code Online (Sandbox Code Playgroud) 我们正在开发一个引用一些COM库的C#应用程序(例如AutoIT).
我在源控件下包含所有引用的组件,在第三方"Libs"文件夹中.
问题是COM dll在.csproj文件中没有HintPath属性,我认为必须使用regsvr32(或使用某种脚本)手动注册这些属性.
我目前正在寻找创建一个将在每次构建之前运行的MSBuild脚本,但是我无法弄清楚我应该手动调用regsvr32.exe还是使用一些预定义的MSBuild任务?
目前,这是我作为测试所支持的:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<ItemGroup>
<MyAssemblies Include="D:\*.dll" />
</ItemGroup>
<Target Name="Build">
<RegisterAssembly
Assemblies="@(MyAssemblies)" >
</RegisterAssembly>
</Target>
</Project>
Run Code Online (Sandbox Code Playgroud)
这会生成我在给定文件夹中放置的DLL不是有效DLL的错误.
什么是这个问题的好方法?
编辑:
引用COM dll的项目在.csproj文件中有类似的内容:
<COMReference Include="AutoItX3Lib">
<Guid>{F8937E53-D444-4E71-9275-35B64210CC3B}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
</COMReference>
Run Code Online (Sandbox Code Playgroud)
这不包括任何提示路径作为其他托管程序集,因此在构建服务器上,找不到引用的COM dll.
使用REGSVR32在构建服务器上注册COM dll时,构建成功.
我的一位同事在VB.net中创建了一个程序集,用于通过COM互操作与JScript一起使用.组件过去工作正常,但我们签了它,现在它似乎只适用于Windows 7机器.我测试了2台Windows 7机器和2台Windows Vista机器.
当我们签署程序集并尝试在JScript中实例化ActiveX对象时,将返回一个错误,但没有消息,只有一个数字:
错误:
错误号:-2146234304
在Google上搜索错误编号并没有太多回复.
如果我们从程序集中删除强名称,它就可以正常工作.关于什么可能是问题的任何想法?不确定它是否有所作为,但正在使用VS 2010编译和签署程序集.
com-interop ×10
c# ×6
.net ×5
com ×3
interop ×2
arrays ×1
asp-classic ×1
assemblies ×1
gac ×1
javascript ×1
marshalling ×1
memory-leaks ×1
msbuild ×1
office-pia ×1
registry ×1
strongname ×1
vb6 ×1
windows-xp ×1