标签: com-interop

从托管进程中切断.NET COM Interop程序集

当ActiveXObject托管在Windows桌面/边栏小工具中时,该ActiveXObject会被缓存,并且其DLL文件被锁定(意味着它无法移动,删除或重命名).问题是这样的; 当小工具随后关闭时,DLL仍然被Windows边栏锁定,无法删除.这导致了一个严重的问题,即新版本的小工具无法安装在小工具的先前版本的顶部,在删除它的过程中失败而没有任何错误消息.

这不是非常用户友好,所以我正在寻找一种方法来在小工具的卸载事件中以某种方式"切断"与ActiveX控件的联系.我希望有人可以告诉我这是否可能,以及是否给我一些关于如何实现它的想法.

仅供参考,Windows边栏小工具实际上只是Internet Explorer服务器窗口,因此假设IE表现出相同的行为可能是安全的.

编辑: Unlocker似乎做了我需要做的事情,所以如何在.NET中以编程方式实现相同的功能呢?

.net winapi activex com-interop handle

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

如何优雅地防止 Web 服务代理暴露给 COM?

我有一个 C# 程序集,用作非托管 C++ 应用程序使用的进程内 COM 服务器。该程序集使用永远不会更改的 Web 服务,因此无需更新 Web 服务代理类。这就是为什么代理类被创建一次,Reference.cs文件被简单地放入存储库中并仅从那里进行编译。

问题是默认情况下 Web 服务代理类是公共的,因此暴露给 COM。这会导致类型库膨胀并污染注册表。将可见性更改为内部会破坏程序集,因此这些实体需要保持公共状态,但不需要暴露给 COM。

愚蠢的方法是接近文件中的每个公共接口/类Reference.cs并将其标记为

[System.Runtime.InteropServices.ComVisible(false)]
Run Code Online (Sandbox Code Playgroud)

此后,它不再暴露于 COM。

有没有更好的办法?

.net c# com com-interop visual-studio

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

如何让MSBuild生成与平台无关的COMReference?

我最近将所有测试项目从dotnet 4切换到了dotnet 3.5(因为我想在CLR 2.0下测试代码(见这里).大多数工作正常,但是一个测试项目依赖于IWshRuntimeLibrary.这由以下csproj指定片段:

<COMReference Include="IWshRuntimeLibrary">
  <Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
  <VersionMajor>1</VersionMajor>
  <VersionMinor>0</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>tlbimp</WrapperTool>
  <Isolated>False</Isolated>
  <EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
Run Code Online (Sandbox Code Playgroud)

我们将测试项目构建为"AnyCPU".当测试项目是.Net 4时,这似乎产生了一个ANYCPU interop dll.现在它是.Net 3.5,interop dll是x86,它System.BadImageFormatException在64位平台上运行时.在降级测试项目之前没有发生此问题.

c# com com-interop platform-independent

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

如何在.NET中释放COM句柄

我在ASP.NET 4.0框架下使用以下代码从Web应用程序获取MSI文件的版本:

string strVersion = "";

try
{
    Type InstallerType;
    WindowsInstaller.Installer installer;

    InstallerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
    installer = (WindowsInstaller.Installer)Activator.CreateInstance(InstallerType);

    WindowsInstaller.Database db = installer.OpenDatabase(strMSIFilePath, 0);

    WindowsInstaller.View dv = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'");

    WindowsInstaller.Record record = null;

    dv.Execute(record);

    record = dv.Fetch();

    strVersion = record.get_StringData(1).ToString();

    dv.Close();
    //db.Commit();
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(dv);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(db);
}
catch
{
    //Failed
    strVersion = "";
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但是当代码完成运行时它保存一个内部MSI文件句柄,所以当我尝试移动或重命名MSI文件时,我得到文件仍在使用的错误.这一直持续到我实际离开调用上述方法的ASPX页面.

我的问题是,我显然没有在上面的代码中关闭一些句柄或对象.但这可能是什么?

PS.我正在VS2010的开发IDE中测试它.

编辑:编辑代码应该是在阿德里亚诺的建议之后.谢谢!

.net c# asp.net windows-installer com-interop

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

在C#中创建IStream对象

我正在编写一个项目并使用另一方DLL.

他们的DLL函数想要一个IStream对象来保存结果,但我无法理解如何创建一个IStream对象.

任何人都可以帮我解决我的问题吗?

c# com com-interop

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

使 C# 类库在 Visual Studio 2022 中 COM 可见

我的最终目标是用 C# 构建一个类库 (Calculator.dll),其中包含可通过 VBA 访问 Excel 的函数。

我本来希望避免注册 dll 的需要,而是在 VBA 代码中使用 Declare Function 语句,但显然这是不可能的,我的研究表明我需要使类库 COM-Visible,然后注册并将其添加为 VBA 项目的引用。在早期的 Visual Studio 版本中,这似乎是单击项目属性对话框中的框的问题,但我在 VS2022 中没有看到该框?!

这些是我对“玩具”示例采取的步骤,以及我遇到的问题。

(1) 我用一个计算类和一个简单的方法来添加两个整数,构建了以下 .dll。由于我们使用 32 位 Excel,因此我将其配置为 x86。

namespace ClassLibraryCalculator
{
    public class Calculate
    {
        public int Add(int a,int b){ return a + b; }
    }
} 
Run Code Online (Sandbox Code Playgroud)

(2) 在命令提示符下,以管理员身份运行,我尝试运行 regsvr32“ClassLibraryCalculator.dll”,但遇到错误“..已加载,但未找到入口点 DllRegisterServer”

经过搜索,据说解决这个问题的方法是修改项目属性,这是(在早期版本的VS中?)一个对话框 在此输入图像描述

带有一个复选框,但我在 Visual Studio 2022 项目属性中没有看到任何与 COM 相关的内容。

.net c# com dll com-interop

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

无法在经典ASP/VBScript页面中实现.Net COM对象(错误ASP 0177)

我使用.Net 3.5在C#中编写了一个支持COM interop的类库.该对象旨在为经典ASP页面提供一些实用程序功能.我编写了一个test.asp页面,该页面实例化了所需的对象并调用了它的方法.在我的机器上正常工作.

在另一台计算机(Windows Server 2003 - 标准版)上,虽然正确地向regasm注册了程序集,但它不起作用.我已经检查了注册表并且看起来没问题.

我得到的错误是"ASP 0177"(错误代码),"8000ffff; Server.CreateObject-Fehler"(错误描述),它转换为Server.CreateObject-Error.

顺便说一句.程序集已签名,并且没有任何其他自定义构建程序集作为依赖项(只是系统内容).

有人经历过类似的事吗?

.net com-interop createobject asp-classic

2
推荐指数
1
解决办法
5021
查看次数

VB6数组语法中的双括号(从.Net com-interop传递)

我有一个C#dll通过com-interop暴露给vb6.这一切都有效,但是当我将.Net的自定义对象数组传递给VB6时,我注意到了一些奇怪的事情.

从VB6访问数组让我感到困惑.如果我直接访问数组,我必须这样做:

Dim manager as New ObjectManager

'Access with two sets of parentheses:
msgbox manager.ReturnArrayOfObjects()(0).Name
Run Code Online (Sandbox Code Playgroud)

但是,如果我先复制数组,我可以访问它通常所期望的:

Dim manager as New ObjectManager
Dim objectArray() As CustomObject

'copy the array
objectArray = manager.ReturnArrayOfObjects

'access normally:
msgbox objectArray(0).Name  
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,我不得不用2套括号:manager.ReturnArrayOfObjects()(0).Name 在第二种情况下,我可以只使用一个括号中:objectArray(0).Name

有谁知道为什么会这样?我可能在这里做错了吗?

这是C#interop代码的快速存根/示例.

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("[Guid here...]")]
public interface IObjectManager
{
    [DispId(1)]
    CustomObject[] ReturnArrayOfObjects();
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("[guid here...]")]
public class ObjectManager: IObjectManager
{
    public CustomObject[] ReturnArrayOfObjects()
    {
        return new CustomObject[] { new CustomObject(), …
Run Code Online (Sandbox Code Playgroud)

c# arrays vb6 com-interop

2
推荐指数
1
解决办法
717
查看次数

C#中_bstr_t的等价物是什么

我正在开发一个项目,我需要将C++代码转换为C#.

_bstr_t在代码中遇到了我想知道C#中的等价物.

.net c# c++ com-interop

2
推荐指数
1
解决办法
1348
查看次数

是否可以通过COM互操作转发代表?

我有一节课:

public class A
{
public delegate void SetTextDel(string value);
public void Test()
{
      SetTextDel setText = someInterface.SetText;
      icom.Set(setText);
}
}

[ComVisible(true), Guid("81C99F84-AA95-41A5-868E-62FAC8FAC263"),   InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface Icom
    {
        void Set(Delegate del);
    }

[ComVisible(true)]
    [Guid("6DF6B926-8EB1-4333-827F-DD814B868097")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(Icom))]
    public class B : Icom
    {
         Set(Delegate del)
         {
              del.DynamicInvoke("some text");
         }
    }
Run Code Online (Sandbox Code Playgroud)

我在Set(Delegate del)中获得了targetinvocation异常.有没有更好的方法来转发委托作为参数?或者我在这里犯了一些我没有看到的错误.我想做的是将someInterface.SetText这个方法作为参数传递.谢谢你的帮助.

.net c# com com-interop visual-studio-2012

2
推荐指数
1
解决办法
734
查看次数