Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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++ CLR主机没有';不执行WPF应用程序,但它不执行WinForms_C++_Wpf_Clr - Fatal编程技术网

C++ CLR主机没有';不执行WPF应用程序,但它不执行WinForms

C++ CLR主机没有';不执行WPF应用程序,但它不执行WinForms,c++,wpf,clr,C++,Wpf,Clr,我制作了一个非常类似于的代码。两者的区别在于,我从内存加载可执行文件,而他从文件加载。另一个区别是他调用了一些随机方法,而我想调用Main方法 我的目标是成为.NETreactor的本地加载程序 该代码适用于控制台应用程序和WinForms。唯一的问题是它不会加载WPF应用程序,更具体地说,它在这一行失败:pMethodInfo->Invoke_3(v2、p2和v)与hr=0x8013164(COR_E__targetinthival)。WPF项目创建于VS2019,目标体系结构(x86)和.N

我制作了一个非常类似于的代码。两者的区别在于,我从内存加载可执行文件,而他从文件加载。另一个区别是他调用了一些随机方法,而我想调用Main方法

我的目标是成为.NETreactor的本地加载程序

该代码适用于控制台应用程序和WinForms。唯一的问题是它不会加载WPF应用程序,更具体地说,它在这一行失败:
pMethodInfo->Invoke_3(v2、p2和v)
hr=0x8013164(COR_E__targetinthival)
。WPF项目创建于VS2019,目标体系结构(x86)和.NET Framework(4.0)与loader的相匹配

下图显示了WPF应用程序的主要功能。我真的不知道它为什么会引起TargetInvestment

代码如下:

int LoadAssembly(LPVOID bytes, DWORD size)
{
    HRESULT hr;

    ICLRMetaHost* pMetaHost = NULL;
    ICLRRuntimeInfo* pRuntimeInfo = NULL;
    ICorRuntimeHost* pCorRuntimeHost = NULL;

    IUnknownPtr UnkAppDomain = NULL;
    _AppDomainPtr AppDomain = NULL;

    _AssemblyPtr pAssembly = NULL;
    _MethodInfoPtr pMethodInfo = NULL;

    SAFEARRAY* params = NULL;
    SAFEARRAY* sa = NULL;

    bool bSuccess = false;

    while (!bSuccess)
    {
        // STAThread
        CoInitialize(NULL);

        // Load and start the .NET runtime.
        hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
        if (FAILED(hr))
            break;

        // Get the ICLRRuntimeInfo corresponding to a particular CLR version. It 
        // supersedes CorBindToRuntimeEx with STARTUP_LOADER_SAFEMODE.
        hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
        if (FAILED(hr))
            break;

        // Check if the specified runtime can be loaded into the process. This 
        // method will take into account other runtimes that may already be 
        // loaded into the process and set pbLoadable to TRUE if this runtime can 
        // be loaded in an in-process side-by-side fashion.
        BOOL fLoadable;
        hr = pRuntimeInfo->IsLoadable(&fLoadable);
        if (FAILED(hr) || !fLoadable)
            break;

        // Load the CLR into the current process and return a runtime interface 
        // pointer. ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting  
        // interfaces supported by CLR 4.0. Here we demo the ICorRuntimeHost 
        // interface that was provided in .NET v1.x, and is compatible with all 
          // .NET Frameworks. 
        hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_PPV_ARGS(&pCorRuntimeHost));
        if (FAILED(hr))
            break;

        // Start the CLR
        hr = pCorRuntimeHost->Start();
        if (FAILED(hr))
            break;

        // Get a pointer to the default AppDomain in the CLR
        hr = pCorRuntimeHost->GetDefaultDomain(&UnkAppDomain);
        if (FAILED(hr))
            break;

        hr = UnkAppDomain->QueryInterface(IID_PPV_ARGS(&AppDomain));
        if (FAILED(hr))
            break;

        SAFEARRAYBOUND sab[1];
        sab[0].lLbound = 0;
        sab[0].cElements = size;

        sa = SafeArrayCreate(VT_UI1, 1, sab);
        if (!sa)
            break;

        void* sa_raw;
        hr = SafeArrayAccessData(sa, &sa_raw);
        if (FAILED(hr))
            break;

        memcpy(sa_raw, bytes, size);

        SafeArrayUnaccessData(sa);

        hr = AppDomain->Load_3(sa, &pAssembly);
        if (FAILED(hr))
            break;

        hr = pAssembly->get_EntryPoint(&pMethodInfo);
        if (FAILED(hr))
            break;

        SAFEARRAY* mtd_params;
        hr = pMethodInfo->GetParameters(&mtd_params);
        if (FAILED(hr))
            break;

        SAFEARRAY* p2;

        if (mtd_params->rgsabound->cElements != 0)
        {
            INT argc;
            WCHAR** _argv = CommandLineToArgvW(GetCommandLineW(), &argc);

            params = SafeArrayCreateVector(VT_BSTR, 0, argc);
            if (!params)
                break;

            for (int i = 0; i < argc; i++) 
            {
                long lIndex = i;

                hr = SafeArrayPutElement(params, &lIndex, SysAllocString(_argv[i]));
                if (FAILED(hr))
                    break;
            }

            p2 = SafeArrayCreateVector(VT_VARIANT, 0, 1);
            LONG l2 = 0;
            VARIANT vp2;

            vp2.vt = VT_ARRAY | VT_BSTR;
            vp2.parray = params;
            hr = SafeArrayPutElement(p2, &l2, &vp2);
            if (FAILED(hr))
                break;
        }
        else
        {
            SAFEARRAYBOUND sabc[1];
            sabc[0].cElements = 0;
            sabc[0].lLbound = 0;

            p2 = SafeArrayCreate(VT_VARIANT, 1, sabc);
        }

        VARIANT v;
        VARIANT v2;
        VariantInit(&v);
        VariantInit(&v2);
        hr = pMethodInfo->Invoke_3(v2, p2, &v);
        VariantClear(&v);
        VariantClear(&v2);
        if (FAILED(hr))
            break;

        bSuccess = true;
    }

    if (pMetaHost)
        pMetaHost->Release();
    if (pRuntimeInfo)
        pRuntimeInfo->Release();
    if (pCorRuntimeHost)
    {
        // Please note that after a call to Stop, the CLR cannot be 
        // reinitialized into the same process. This step is usually not 
        // necessary. You can leave the .NET runtime loaded in your process.
        pCorRuntimeHost->Stop();
        pCorRuntimeHost->Release();
    }
    if (sa)
        SafeArrayDestroy(sa);
    if (params)
        SafeArrayDestroy(params);

    return hr;
}
这与我在C++代码中收到的错误相同,只是我不太确定如何检查其中的内部异常

我做了一些研究,我意识到我必须改变
ResourceAssembly
,就像他们在这里做的那样:。新代码如下所示:

byte[] data = File.ReadAllBytes("Test2.exe");
Assembly assembly = Assembly.Load(data);

Type type = typeof(Application);

FieldInfo field = type.GetField("_resourceAssembly", BindingFlags.NonPublic | BindingFlags.Static);
field.SetValue(null, assembly);

Type helper = typeof(BaseUriHelper);
PropertyInfo property = helper.GetProperty("ResourceAssembly", BindingFlags.NonPublic | BindingFlags.Static);
property.SetValue(null, assembly, null);

assembly.EntryPoint.Invoke(null, new object[0]);
结果是代码加载了WPF应用程序。现在,问题是我如何在C++代码中实现这一点?似乎没有人处理过这个问题。我找到的唯一解决方案是从磁盘而不是内存加载文件-。

我找到了这个示例:它适用于WPF,但问题是他们是从文件而不是内存加载文件。我想从内存中加载它。你知道怎么做吗?
byte[] data = File.ReadAllBytes("Test2.exe");
Assembly assembly = Assembly.Load(data);

Type type = typeof(Application);

FieldInfo field = type.GetField("_resourceAssembly", BindingFlags.NonPublic | BindingFlags.Static);
field.SetValue(null, assembly);

Type helper = typeof(BaseUriHelper);
PropertyInfo property = helper.GetProperty("ResourceAssembly", BindingFlags.NonPublic | BindingFlags.Static);
property.SetValue(null, assembly, null);

assembly.EntryPoint.Invoke(null, new object[0]);