[C++/WinRT] load C++/WinRT dll without application manifest

lunadev 1 Reputation point
2020-03-13T06:20:27.713+00:00

I'm writing a dll and using Windows Vision Skill (C++/WinRT) to process image. Since Windows Skill (C++/WinRT) need application manifest to load its DLL, unfortunately I don't have permission to edit application manifest, my DLL is loaded automatically by system process. I got the error "ClassFactory cannot supply requested class" when creating C++/WinRT object.

I also tried to use Activation Context API to activate the context, but nothing changed.

Here is the code I use to start create object via wrapper, the below code is executed when my dll is attached:

Wrapper* pwrap = new Wrapper();

    ACTCTX actCtx;
    memset((void*)&actCtx, 0, sizeof(ACTCTX));
    actCtx.cbSize = sizeof(ACTCTX);
    actCtx.lpSource = PathToManifest(); 

    HANDLE hCtx = ::CreateActCtx(&actCtx);
    if (hCtx == INVALID_HANDLE_VALUE)
        DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "CreateActCtx returned: INVALID_HANDLE_VALUE");
    else
    {
        ULONG_PTR cookie;
        if (::ActivateActCtx(hCtx, &cookie))
        {

            S_Error err_res = pwrap->Create();

            ::DeactivateActCtx(0, cookie);
        }
    }

Here is the c++/winrt creating code:

bool Wrapper::Create()
{
    bool err = false;

    try {

        // Create the ObjectDetector skill descriptor
        auto skillDescriptor = ObjectDetectorDescriptor().as<ISkillDescriptor>();

        // Create instance of the skill
        ObjectDetectorSkill Skill = skillDescriptor.CreateSkillAsync().get().as<ObjectDetectorSkill>();

        // Create instance of the skill binding
        ObjectDetectorBinding Binding = Skill.CreateSkillBindingAsync().get().as<ObjectDetectorBinding>();

        err = true;
    }
    catch (hresult_error const& ex)
    {
        std::wstring wbuf = ex.message().c_str();
        int wleng = wbuf.length();
        char* buf = new char[wleng];
        size_t len;
        errno_t  error = wcstombs_s(&len, (char*)(buf), 255, wbuf.c_str(), 255);
        UNREFERENCED_PARAMETER(len);
        UNREFERENCED_PARAMETER(error);

        m_error = buf;
    }

    return err;
}

Here is the manifest file and all DLLs are put into same directory:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity type="win32" name="Wrapper" version="1.0.0.0" ></assemblyIdentity>
    <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.AI.Skills.SkillInterfacePreview" version="1.0.0.0"></assemblyIdentity>
    </dependentAssembly>
  </dependency>

  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.AI.Skills.Vision.ObjectDetectorPreview" version="1.0.0.0"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

I think the problem is the Windows Skill (C++/WinRT) DLL cannot be loaded, so I cannot create the object.

Does anyone know how to load C++/WinRT inside other dll without modifying application manifest? Please help me.

Universal Windows Platform (UWP)
{count} votes