Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 托管注册免费COM服务器赢得';t激活_C#_C++_Com_Vb6_Regfreecom - Fatal编程技术网

C# 托管注册免费COM服务器赢得';t激活

C# 托管注册免费COM服务器赢得';t激活,c#,c++,com,vb6,regfreecom,C#,C++,Com,Vb6,Regfreecom,我从一个非常复杂的客户端和服务器系统开始,该系统包含COM引用和其他内容,我不断地缩减,直到我意识到我甚至无法让Microsoft示例代码用于以C#编写的托管COM服务器的免注册COM激活 服务器代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices.ComTypes; using System.Ru

我从一个非常复杂的客户端和服务器系统开始,该系统包含COM引用和其他内容,我不断地缩减,直到我意识到我甚至无法让Microsoft示例代码用于以C#编写的托管COM服务器的免注册COM激活

服务器代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace ClassLibrary1
{
   [Guid("A7AC6D8C-FF17-4D2C-A3B1-2C8690A8EA04")
   ,ComVisible(true)]
   public interface IClass1
   {
      [DispId(1)]
      string DummyFunction(string inputValue);
   }

   [Guid("81723475-B5E3-4FA0-A3FE-6DE66CEE211C"),
   ClassInterface(ClassInterfaceType.None),
   ComDefaultInterface(typeof(IClass1)),
   ComVisible(true)]
   public class Class1 : IClass1
   {
      public string DummyFunction(string inputValue)
      {
         return inputValue.Substring(0, 1) + " Inserted " + inputValue.Substring(1);
      }
   }
}
客户端VB6代码:

Dim c As ClassLibrary1.Class1
集合c=新类别1
MsgBox c.dummy函数(“Ben”)

客户端C++代码:

#include "stdafx.h"

#import <ClassLibrary1.tlb> raw_interfaces_only

using namespace ClassLibrary1;

int _tmain(int argc, _TCHAR* argv[])
{
   IClass1Ptr p;

   HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
   hr = CoCreateInstance(__uuidof(Class1), NULL, CLSCTX_INPROC_SERVER, __uuidof(IClass1), (void **)&p);
   if (FAILED(hr))
   {
      _tprintf_s(_T("Error %x\n"), hr);
      CoUninitialize();
      return 1;
   }
   _bstr_t b = _T("Bobby");
   BSTR b2;
   p->DummyFunction(b, &b2);
   wprintf_s(L"%s\n", b2);
   p->Release();
   CoUninitialize();
    return 0;
}

#包括“stdafx.h”
#仅导入原始接口
使用命名空间ClassLibrary1;
int _tmain(int argc,_TCHAR*argv[]
{
IClass1Ptr p;
HRESULT hr=coinitializex(NULL,COINIT\u多线程);
hr=CoCreateInstance(uuuIdof(Class1),NULL,CLSCTX_INPROC_U服务器,uuuIdof(IClass1),(void**)和p);
如果(失败(小时))
{
_tprintf_s(_T(“错误%x”),hr);
coninitialize();
返回1;
}
_bstr_t b=_t(“Bobby”);
BSTR b2;
p->dummy函数(b和b2);
wprintf_s(L“%s\n”,b2);
p->Release();
coninitialize();
返回0;
}
当我删除所有Reg Free COM代码并用regasm/codebase注册ClassLibrary1.dll时,这两个客户端都可以正常工作

然后我注销ClassLibrary1,并尝试使用Project1.exe.manifest文件为VB6客户端引入Reg Free COM:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <assemblyIdentity type="win32" name="Project1" version="1.0.0.0" />
   <dependency>
   <dependentAssembly>
   <assemblyIdentity name="ClassLibrary1" version="1.0.0.0" />
   </dependentAssembly>
   </dependency>
</assembly>
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
   <assemblyIdentity version="1.0.0.0" name="ClassLibrary1" />
   <clrClass clsid="{81723475-B5E3-4FA0-A3FE-6DE66CEE211C}" name="ClassLibrary1.Class1" tlbid="{F8A2D334-5BBB-4007-8308-A1417052E6D6}"></clrClass>
   <file name="ClassLibrary1.dll" ></file>
</assembly>

现在运行C++客户端时,输出仅为

错误800401f9


在使用微软支持进行各种测试的许多试验之后,我发现了在试图用非托管C++ COM客户端实现托管COM服务器时出现的许多缺陷。下面是我记得的一些关键信息,它们可以应用于问题中的示例代码,以确保其工作正常

  • 客户端不应在C++项目中使用孤立的COM设置。我的内存正在衰退,但Microsoft支持人员告诉我,这是为了其他目的——我认为是为了开发一个到非托管COM服务器而不是托管COM服务器的独立COM接口。虽然这一点从其在的描述中根本不清楚
  • 客户端可以为“嵌入清单”设置选择“是”或“否”,但如果选择了“是”,则包含依赖程序集信息的清单必须作为输入清单文件提供。如果嵌入的清单不包含依赖程序集信息,则将忽略任何外部清单文件。另外,确保正在编辑的配置(例如调试)与正在测试的配置匹配!
  • 如果COM服务器使用密钥(强名称)签名,则客户端清单和服务器清单中的assemblyIdentity元素都必须包含publicKeyToken,否则在CoCreateInstance期间将发生HRESULT错误0x8013100
  • 在Visual Studio 2013中,将RT#U清单资源作为Win32资源嵌入托管代码并不容易,因为C#和VB.NET项目倾向于将资源作为托管.NET资源而不是Win32资源嵌入(您可以通过使用资源查看器打开DLL输出文件来验证这一点,请注意,.NET可执行文件通常会获得一个版本资源,而不会获得太多其他资源,即使项目中包含清单文件)。解决此问题的一种方法是创建一个如下所示的RC文件:
  • -

    然后添加如下预构建步骤:

    "C:\Program Files (x86)\Windows Kits\8.1\bin\x86\rc.exe"  "$(ProjectDir)ClassLibrary1.rc"
    
    然后在项目设置“应用程序”选项卡中,将“资源”更改为使用ClassLibrary1.res,而不是“图标和清单”。但这也带来了一些问题:首先,如果不对RC.EXE进行硬编码,它的路径很难定义;其次,AssemblyInfoCommon中的版本信息将被忽略,因为RC文件中的资源将完全替换.NET编译器生成的所有Win32资源

    另一种可能是简单地将服务器COM DLL清单文件分开,而不是将其作为资源嵌入。我已经了解到这可能不可靠,但它可以在Windows 7 Enterprise 64位SP1上工作

  • 为了确保非托管客户端加载正确的.NET运行时,它需要一个定义如何加载.NET.For.NET 4.5的配置文件(
    ConsoleApplication1.exe.config
    ),我看到了以下工作:
  • -

  • 此时,此解决方案中前面提到的步骤似乎有点过于复杂。您可以通过显示隐藏文件并在清单文件上使用“include in project”命令,将清单文件包含在项目中
  • 此时运行将显示错误消息“应用程序无法启动,因为其并行配置不正确。有关详细信息,请参阅应用程序事件日志或使用命令行sxstrace.exe工具。”这部分是因为我们没有将ClassLibrary1.dll放在ConsoleApplication1.exe可以找到它的任何位置。此时解析的sxstrace输出如下所示:
  • -

  • 将ClassLibrary1.dll文件复制到与ConsoleApplication1.exe相同的目录中不会改变任何内容,因为我们没有为该文件提供任何清单,通过该清单可以识别COM依赖项。因此,下一步是为ClassLibrary1创建清单。问题中已经存在ClassLibrary1.manifest的一个版本。让我们通过创建一个包含该内容的文本文件并将其保存在ClassLibrary1项目目录中作为ClassLibrary1.manifest来尝试这个方法。要将其包含在项目中,让我们尝试同样简单的“包含在项目中”命令(再次打开隐藏文件的可见性以实现此目的).现在,如果使用ConsoleApplication1.exe将新的ClassLibrary1.dll复制到目录并运行,会发生什么情况
  • 出现相同的错误和sxstrace结果是因为托管DLL中的清单文件没有作为Win32资源嵌入,您可以通过使用Visual Studio打开DLL文件来验证这一点,该文件显示了该文件的Win32资源。它显示了版本资源,而没有其他内容。因此,让我们从类中排除清单
    "C:\Program Files (x86)\Windows Kits\8.1\bin\x86\rc.exe"  "$(ProjectDir)ClassLibrary1.rc"
    
    <configuration>
      <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0"/>
      </startup>
    </configuration>
    
    <configuration>
      <startup useLegacyV2RuntimeActivationPolicy="false">
        <supportedRuntime version="v3.5"/>
      </startup>
    </configuration>
    
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    
    <assemblyIdentity
                type = "win32"
                name = "ConsoleApplication1"
                version = "1.0.0.0" />
    <dependency>
                <dependentAssembly>
                            <assemblyIdentity
                                        type="win32"
                                        name="ClassLibrary1"
                                        version="1.0.0.0"
                                        publicKeyToken="541b4aff0f04b60a"/>
                </dependentAssembly>
    </dependency>
    </assembly>
    
    <?xml version="1.0" encoding="utf-8"?>
    <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
       <assemblyIdentity type="win32" name="ClassLibrary1" version="1.0.0.0" publicKeyToken="541b4aff0f04b60a" />
       <clrClass clsid="{81723475-B5E3-4FA0-A3FE-6DE66CEE211C}" progid="ClassLibrary1.Class1" threadingModel="both" name="ClassLibrary1.Class1" runtimeVersion="v2.0.50727"></clrClass>
    </assembly>
    
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
       <assemblyIdentity type="win32" name="ConsoleApplication1" version="1.0.0.0" />
       <dependency>
       <dependentAssembly>
       <assemblyIdentity name="ClassLibrary1" version="1.0.0.0" />
       </dependentAssembly>
       </dependency>
    </assembly>
    
    INFO: Parsing Manifest File C:\Users\bmarty\Documents\Visual Studio 2013\Projects\RegFreeCOM\Debug\ConsoleApplication1.exe.
        INFO: Manifest Definition Identity is ConsoleApplication1,type="win32",version="1.0.0.0".
        INFO: Reference: ClassLibrary1,version="1.0.0.0"
    INFO: Resolving reference ClassLibrary1,version="1.0.0.0".
        INFO: Resolving reference for ProcessorArchitecture ClassLibrary1,version="1.0.0.0".
            INFO: Resolving reference for culture Neutral.
                INFO: Applying Binding Policy.
                    INFO: No binding policy redirect found.
                INFO: Begin assembly probing.
                    INFO: Did not find the assembly in WinSxS.
                    INFO: Attempt to probe manifest at C:\Users\bmarty\Documents\Visual Studio 2013\Projects\RegFreeCOM\Debug\ClassLibrary1.DLL.
                    INFO: Attempt to probe manifest at C:\Users\bmarty\Documents\Visual Studio 2013\Projects\RegFreeCOM\Debug\ClassLibrary1.MANIFEST.
                    INFO: Attempt to probe manifest at C:\Users\bmarty\Documents\Visual Studio 2013\Projects\RegFreeCOM\Debug\ClassLibrary1\ClassLibrary1.DLL.
                    INFO: Attempt to probe manifest at C:\Users\bmarty\Documents\Visual Studio 2013\Projects\RegFreeCOM\Debug\ClassLibrary1\ClassLibrary1.MANIFEST.
                    INFO: Did not find manifest for culture Neutral.
                INFO: End assembly probing.
        ERROR: Cannot resolve reference ClassLibrary1,version="1.0.0.0".
    ERROR: Activation Context generation failed.
    End Activation Context Generation.
    
    <configuration>
      <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0"/>
      </startup>
    </configuration>
    
    <configuration>
      <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0"/>
      </startup>
    </configuration>
    
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
       <assemblyIdentity type="win32" name="Project1" version="1.0.0.0" />
       <dependency>
       <dependentAssembly>
       <assemblyIdentity name="ClassLibrary1" version="1.0.0.0" publicKeyToken="541b4aff0f04b60a" />
       </dependentAssembly>
       </dependency>
    </assembly>
    
    <PropertyGroup>
      <ApplicationManifest>app.manifest</ApplicationManifest>
    </PropertyGroup>
    
    WRN: Comparing the assembly name resulted in the mismatch: Major Version
    ERR: The assembly reference did not match the assembly definition found.
    ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
    
    copy /b myfile.exe+,,
    
    ACTCTX context;
    memset(&context, 0, sizeof(context));
    
    context.cbSize = sizeof(context);
    context.lpSource = L"CPPClient.exe.manifest";
    context.lpAssemblyDirectory = L"D:\\code\\vs2017\\CPPClient\\Debug";
    context.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID; 
    
    HANDLE hActCtx = CreateActCtx(&context);
    
    ULONG_PTR cookie = 0;
    BOOL result = ActivateActCtx(hActCtx, &cookie);
    
    //Rest of the code goes here.
    
    DeactivateActCtx(0, cookie);
    ReleaseActCtx(hActCtx);