为什么即使getlasterror为0,为什么clrhosting api也无法正常工作
Why CLRHosting API not working even if the GetLastError is 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.nn" +
"I am running inside: [" +
System.Diagnostics.Process.GetCurrentProcess().ProcessName +
"]nn" + (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链接,它应该显示对话框,但在我的情况下,它没有显示任何内容。
我不确定问题,任何建议/指针都会有所帮助。谢谢。
托管API使用com,它不会通过getlastror()报告错误。该方法的返回值是错误代码。它是一个hresult,托管API通常返回错误代码,例如0x8013xxxx。您会在Corror.h sdk标头中找到xxxx值。
您需要这样的东西:
hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(...);
if (FAILED(hr)) ErrorExit(L"Execute", hr);
并将此支票添加到每个调用您进行的。不这样做可能会使您的程序以难以诊断的方式崩溃。而且您需要所有的帮助,您将不再有友好的.NET例外来告诉您出了什么问题。
其他生存策略正在使用混合模式调试,因此您可以在诊断托管例外诊断,然后在他们变成hresult之前,撰写AppDomain.CurrentDomain.unhandledDomain.unhandledException事件在您的托管代码中使用IERRORINFO,以便您可以得到例外主机中的消息,使用正确的方法名称,它是l"入口点",并根据需要将其制作 static 。
相关文章:
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 为什么我的 std::ref 无法按预期工作?
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- 有人能解释一下为什么下界是这样工作的吗C++的
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 为什么stream::忽略未按预期工作
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 为什么 HeapFree() 不能正常工作?
- 为什么我们将单个或多维数组的大小声明为常量值?
- 抑制警告C4996:为什么不工作
- 为什么STD ::计数将常数传递给Lambda,而不是在弦上工作时而不是字符
- 返回const lvalue引用rvalue临时?为什么这项工作
- 为什么这样工作
- C 参考class对象的返回 - 为什么不工作
- 为什么setMainQmlFile工作,而setSource在相同路径下失败
- 用不重复的随机数填充向量.为什么不工作
- 为什么代码工作良好,当我编译和运行它,即使我没有提到数组的大小
- 为什么RegSetValueEx工作,即使我打破了关于会计NUL终止长度的规则
- Visual Studio MFC in C++:为什么"int"工作而不"double"?
- C /c++ hackerrank,我的代码是工作的,但我得到0.38 /10分(不知道为什么)代码工作