Почему CLRHosting API не работает, даже если GetLastError равен 0?

Я пытаюсь загрузить управляемый C # DLL в управляемый процесс C #, следуя этому руководство. Я немного потрудился на C / C ++ и имею практические знания по MS COM, но C # и управляемый код — это совершенно новый для меня зверь, так что будьте добры, если я что-то делаю не так. У меня есть .NET 4.5 в моей системе, и это та же среда выполнения, которая используется по умолчанию (я думаю). Код на данный момент (в основном, скопирован из ссылки выше):

Код — C #

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace InjectSample
{
public class Program
{
int EntryPoint(String pwzArgument)
{
System.Media.SystemSounds.Beep.Play();

MessageBox.Show(
"I am a managed app.\n\n" +
"I am running inside: [" +
System.Diagnostics.Process.GetCurrentProcess().ProcessName +
"]\n\n" + (String.IsNullOrEmpty(pwzArgument) ?
"I was not given an argument" :
"I was given this argument: [" + pwzArgument + "]"));

return 0;
}

static void Main(string[] args)
{
Program prog = new Program();
prog.EntryPoint("hello world");
}
}
}

Родной код

#include <metahost.h>
#pragma comment(lib, "mscoree.lib")
#import "mscorlib.tlb" raw_interfaces_only \
high_property_prefixes("_get","_put","_putref") \
rename("ReportEvent", "InteropServices_ReportEvent")#include <strsafe.h>
void ErrorExit(LPCWSTR lpszFunction, DWORD dwLastError)
{
if(dwLastError == 0) return;
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dwFlag = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
FormatMessage( dwFlag, NULL, dwLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );

lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), lpszFunction, dwLastError, lpMsgBuf);

::MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}

int wmain(int argc, wchar_t* argv[])
{
HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;

// build runtime
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
IID_PPV_ARGS(&pClrRuntimeHost));

// start runtime
hr = pClrRuntimeHost->Start();

// execute managed assembly
DWORD pReturnValue;
SetLastError(0);
hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(
L"C:\\Temp\\InjectSample.exe",
L"InjectExample.Program",
L"int EntryPoint(String pwzArgument)",
L"hello .net runtime",
&pReturnValue);

ErrorExit(L"ExecuteInDefaultAppDomain()", GetLastError());
// free resources
pMetaHost->Release();
pRuntimeInfo->Release();
pClrRuntimeHost->Release();

return 0;
}

проблема

Теперь проблема в том, что когда я выполняю нативный код, GetLastError() возвращается 0, Это сразу после звонка ExecuteInDefaultAppDomain(), По ссылке Codeproject, она должна была показать диалоговое окно, но в моем случае это ничего не показывает.

Я не уверен в проблеме, любое предложение / указатель будет полезно. Благодарю.

1

Решение

API хостинга использует COM, он не сообщает об ошибках через GetLastError (). Возвращаемым значением метода является код ошибки. Это HRESULT, API хостинга обычно возвращает коды ошибок, например 0x8013xxxx. Вы найдете значения xxxx в заголовке SDK CorError.h.

Вам понадобится что-то вроде этого:

hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(...);
if (FAILED(hr)) ErrorExit(L"Execute", hr);

И добавить эту проверку в каждый позвонить тебе сделать Несоблюдение этого требования может привести к аварийному завершению вашей программы. И вам нужна вся помощь, которую вы можете получить, у вас больше нет дружественных исключений .NET, чтобы сообщить вам, что пошло не так.

В других стратегиях выживания используется отладка в смешанном режиме, поэтому у вас есть шанс диагностировать управляемые исключения, прежде чем они превратятся в HRESULT, написав обработчик событий AppDomain.CurrentDomain.UnhandledException в вашем управляемом коде, используя IErrorInfo, чтобы вы могли получить сообщение об исключении в своем хост, используя правильное имя метода, это L «EntryPoint», и делает его статический как требуется.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]