loadFromRemoteSources in a C++ project

0

I've created a C++ DLL (it must be in C++) which dinamically links a .Net DLL to host a Web Service Server. The .Net DLL passes the web service calls to the C++ DLL, which as evaluated and responded also through the .Net DLL.

Something like that:

     HSPWebService.DLL
-----------------------------------
HSPProxy.DLL | HSPWebServiceLib.DLL
-----------------------------------
      HSPSendData.DLL
  • HSPWebService.DLL - the proper C++ DLL.
  • HSPProxy.DLL - proxy generated by the MIDL compiler over the HSP.DLL MIDL interface.
  • HSPWebServiceLib.DLL - typelib generated by the tlmbimp over the HSP.DLL.
  • HSPSendData.DLL - .Net DLL which hosts the web service server

Everything works like a charm. The problem is when the DLL files are in a network share (//myPc/share). My application log shows the error 0x80131515:

CreateAssemblyInstance ERROR: Could not create an assembly instance. (hr=80131515)

On my research I've found that the 0x80131515 error occurs because the .Net framework won't load assemblies from external sources by default. For .Net projects the option can be set into the project settings. But I have a C++ project on Visual Studio 2010 and I have no clue about using this configuration on my project (or my code). Any ideas?

The CreateAssemblyInstance function:

HRESULT CHSPWebServiceObjectHost::CreateAssemblyInstance(_AppDomain* pDefAppDomain, CComPtr<IDispatch>& spDisp, LPCTSTR pszAsseblyName, LPCTSTR pszClassNameWithNamespace) const
{
  spDisp = NULL;
  REQUIRE_IN_POINTER(pDefAppDomain);
  try
  {
    _bstr_t _bstrAssemblyName(pszAsseblyName);
    _bstr_t _bstrszClassNameWithNamespace(pszClassNameWithNamespace);
    //Creates an Assembly instance
    CComPtr<_ObjectHandle> spObjectHandle;
    HRESULT hr = pDefAppDomain->CreateInstanceFrom(_bstrAssemblyName,   _bstrszClassNameWithNamespace, &spObjectHandle);
    if (FAILED(hr))
    {
      Log(logDriver, _T("CHSPWebServiceObjectHost::CreateAssemblyInstance ERROR: Could not create an assembly instance. (hr=%08X)"), hr);
      return hr;
    }

    CComVariant VntUnwrapped;
    hr = spObjectHandle->Unwrap(&VntUnwrapped);
    if (FAILED(hr))
    {
      Log(logDriver, _T("CHSPWebServiceObjectHost::CreateAssemblyInstance ERROR: Could not unwrap assembly object. (hr=%08X)"), hr);
      return hr;
    }

    spDisp = VntUnwrapped.pdispVal;
  }
  catch (_com_error& e)
  {
    return e.Error();
  }
  return S_OK;
}

It is called by the StartCLR function:

HRESULT CHSPWebServiceObjectHost::StartCLR(CComPtr<ICorRuntimeHost>& spRuntimeHost, CComPtr<IDispatch>& spDispHost) const
{
  spRuntimeHost = NULL;
  spDispHost = NULL;

  //Retrieve a pointer to the ICorRuntimeHost interface
  HRESULT hr = CorBindToRuntimeEx(L"v4.0.30319",
                                  L"wks",
                                  STARTUP_LOADER_SAFEMODE | STARTUP_CONCURRENT_GC, 
                                  CLSID_CorRuntimeHost,
                                  IID_ICorRuntimeHost,
                                  (void**)&spRuntimeHost);

  if (FAILED(hr))
  {
    Log(logDriver, _T("CHSPWebServiceObjectHost::StartCLR ERROR: Could not load CLR into unmanaged host process. (    hr=%08X)"), hr);    
    return hr;    
  }    

  //Start the CLR
  hr = spRuntimeHost->Start();
  if (FAILED(hr))
  {
    Log(logDriver, _T("CHSPWebServiceObjectHost::StartCLR ERROR: Could not start CLR. (hr=%08X)"), hr);
    return hr;
  }

  //Retrieve the IUnknown default AppDomain
  CComPtr<IUnknown> spUnknown;
  hr = spRuntimeHost->GetDefaultDomain(&spUnknown);
  if (FAILED(hr))
  {
    Log(logDriver, _T("CHSPWebServiceObjectHost::StartCLR ERROR: Could not retrieve pointer to domain interface. (    hr=%08X)"), hr);    
    return hr;    
  }    

  CComQIPtr<_AppDomain> spDefAppDomain(spUnknown);
  if (spDefAppDomain == NULL)
    return E_NOINTERFACE;

  CString strAssemblyFullPath = _T(".\\HSPSendData.dll");

  return CreateAssemblyInstance(spDefAppDomain, spDispHost, strAssemblyFullPath, _T("Elipse.HSPWebService.    HSPWebServiceHost"));    
}    
c++
visual-studio-2010
dll
interop
com-interop
asked on Stack Overflow Dec 9, 2013 by Taschetto • edited Dec 9, 2013 by Taschetto

2 Answers

0

Given that your assemblies are located on a network share, you need to add a <loadFromRemoteSources> element to your app.config file. For example:

<configuration>
   <runtime>
      <loadFromRemoteSources enabled="true"/>
   </runtime>
</configuration>

You don't mention your host process, but assuming it is MyService.exe this would go in the file MyService.exe.config.

answered on Stack Overflow Dec 10, 2013 by Holistic Developer
0

Aparently the .NET updates have resolved this issue. I've tried to backtrack which update had it done but I wasn't able to find it.

answered on Stack Overflow Apr 8, 2014 by Taschetto

User contributions licensed under CC BY-SA 3.0