相关疑难解决方法(0)

为免注册COM生成清单文件

我有一些应用程序(一些本机,一些.NET)使用清单文件,以便它们可以完全隔离部署,而无需任何全局COM注册.例如,在myapp.exe.manifest文件中声明对dbgrid32.ocx com服务器的依赖关系如下,该文件与myapp.exe位于同一文件夹中:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity type="win32" name="myapp.exe" version="1.2.3.4" />
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="dbgrid32.ocx" version="5.1.81.4" />
    </dependentAssembly>
  </dependency>
</assembly>
Run Code Online (Sandbox Code Playgroud)

dbgrid32.ocx与它自己的dbgrid32.ocx.manifest文件一起部署到同一文件夹:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity type="win32" name="dbgrid32.ocx" version="5.1.81.4" />
  <file name="dbgrid32.ocx">
     <typelib
        tlbid="{00028C01-0000-0000-0000-000000000046}"
        version="1.0"
        helpdir=""/>
    <comClass progid="MSDBGrid.DBGrid"
       clsid="{00028C00-0000-0000-0000-000000000046}"
       description="DBGrid  Control" />
  </file>
</assembly>
Run Code Online (Sandbox Code Playgroud)

这一切都很好,但手动维护这些清单文件有点痛苦.有没有办法自动生成这些文件?理想情况下,我只想声明应用程序对COM服务器列表(本机和.NET)的依赖性,然后自动生成其余部分.可能吗?

com dll manifest typelib regfreecom

84
推荐指数
4
解决办法
5万
查看次数

免注册COM/DLL?

我的程序正在使用Skype4COM.dll(Skype API的包装器).

我正在使用Delphi 2010 - 有没有办法确保我的程序始终使用我将随附的Skype4COM.dll?问题是,有不同版本的Skype4COM,如果我将我的注册用于别人,他们的应用可能不再适用.

通常我使用RegSvr32在人民系统上注册DLL,但是我听说它可以免费注册(在C#中),所以我的问题是:我们也可以在Delphi中这样做吗?

谢谢!

delphi dll skype dllregistration

29
推荐指数
2
解决办法
8368
查看次数

如何使.NET COM对象成为单元线程?

默认情况下,.NET对象是自由线程的.如果通过COM封送到另一个线程,它们总是被封送到自己,无论创建者线程是否是STA,并且无论其ThreadingModel注册表值如何.我怀疑,他们聚合了Free Threaded Marshaler(有关COM线程的更多细节可以在这里找到).

我想让我的.NET COM对象在封送到另一个线程时使用标准的COM marshaller代理.问题:

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            var apt1 = new WpfApartment();
            var apt2 = new WpfApartment();

            apt1.Invoke(() =>
            {
                var comObj = new ComObject();
                comObj.Test();

                IntPtr pStm;
                NativeMethods.CoMarshalInterThreadInterfaceInStream(NativeMethods.IID_IUnknown, comObj, out pStm);

                apt2.Invoke(() =>
                {
                    object unk;
                    NativeMethods.CoGetInterfaceAndReleaseStream(pStm, NativeMethods.IID_IUnknown, out unk);

                    Console.WriteLine(new { equal = Object.ReferenceEquals(comObj, unk) });

                    var marshaledComObj = (IComObject)unk;
                    marshaledComObj.Test();
                }); …
Run Code Online (Sandbox Code Playgroud)

.net c# com multithreading com-interop

12
推荐指数
2
解决办法
1900
查看次数

无法通过AppDomains传递GCHandle:没有代表的解决方案?

我在c ++中有基础库,客户端应用程序在C#中.有一个c ++/cli接口可以从C#访问c ++ api.一切都运行正常,直到多个应用程序域没有像NUnit或WCF托管一样发挥,即有一个应用程序域.

我已经在cli 中的gcroot中存储了托管对象以进行回调.我已经读过这是应用程序域问题的根本原因("无法通过AppDomains传递GCHandle")因为它们没有应用程序域信息(http://lambert.geek.nz/2007/05/29/unmanaged -appdomain-callback /).有人建议使用委托,但我的基础c ++层期望对象不是函数指针(http://www.lenholgate.com/blog/2009/07/error-cannot-pass-a-gchandle-across-appdomains.html).我也尝试过IntPtr,但在这种情况下,我无法在回调期间将其强制转换为我的托管对象.

UPDATE

让我再详细说明一下我的问题.

我在C#中有"Receiver"类,它作为输入参数传递给api之一.此接收器对象用于回调.在C++/CLI中,我创建了一个Native/unmanaged类"ObjectBinder",它与托管的Receiver类具有相同的副本(具有相同的方法).它保存了gcroot中托管接收者对象的参考.当我们从C#调用api时,它来到CLI层,app域是"client exe".我们在gcroot中的ObjectBinder中存储参数"managed receiver object",并将本机ObjectBinder对象的引用传递给C++.现在后端代码(c ++和c)将一个asyn回调(新线程)发送到c ++层,该层使用ObjectBinder对象向CLI发送回调用.现在我们在ObjectBinder对象的CLI层中.但是App域已被更改(在WCF或NUNIT或任何其他创建它自己的App域的服务的情况下,在编译时不知道).现在我想访问存储在gcroot中的托管Receiver对象,以便将回调发送回C#,但它给出了APP DOMAIN错误.

我也尝试过IntPtrIUnknown*而不是gcrootMarshal :: GetIUnknownForObjectMarshal :: GetObjectForIUnknown但是得到相同的错误.

.net c# com c++-cli com-interop

8
推荐指数
1
解决办法
5014
查看次数

是否可以通过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
查看次数