Given a path to an assembly manifest file, how do we get its full display name, including ProcessorArchitecture?

From my previous discussion, we know there is no managed way to achieve this. We have to use an unmanaged solution.

From the discussion of assembly identity, we know that identities can be reference or definition. In unmanaged fusion we exposed a full programming model on assembly identity. Specifically, we introduced three interfaces: IReferenceIdentity, IDefinitionIdentity, and IIdentityAuthority. IReferenceIdenity represents an assembly reference. IDefinitionIdentity is an assembly definition. IIdentityAuthority is used to compare identities, as well as map the identities and their textual representation (so called assembly display name).

The three interfaces are defined in isolation.h, which is part of .Net framework 2.0 SDK.

The following sample uses those interfaces to get the full display name of an assembly given its path.

//
//  ShowName.cpp
//
//  Show the full display name of an given assembly, including architecture.
//

#include "fusion.h"
#include "windows.h"
#include "stdio.h"
#include "mscoree.h"
#include "isolation.h"

typedef HRESULT (__stdcall *PFNGETREF)(LPCWSTR pwzFile, REFIID riid, IUnknown **ppUnk);
typedef HRESULT (__stdcall *PFNGETAUTH)(IIdentityAuthority **ppIIdentityAuthority);

PFNGETREF                   g_pfnGetAssemblyIdentityFromFile = NULL;
PFNGETAUTH                  g_pfnGetIdentityAuthority = NULL;
IUnknown                    *g_pUnk = NULL;

bool Init()
{
    HRESULT     hr = S_OK;
    DWORD       dwSize = 0;
    bool        bRC = false;
   
    hr = CorBindToRuntimeEx(NULL, L"wks", 0, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void **)&g_pUnk);
    if(FAILED(hr)) {
        printf("Error: Failed to initialize CLR runtime! hr = 0x%0x\n", hr);
        goto Exit;
    }
  
    if (SUCCEEDED(hr)) {
        hr = GetRealProcAddress("GetAssemblyIdentityFromFile", (VOID **)&g_pfnGetAssemblyIdentityFromFile);
    }

    if (SUCCEEDED(hr)) {
        hr = GetRealProcAddress("GetIdentityAuthority", (VOID **)&g_pfnGetIdentityAuthority);
    }

    if (!g_pfnGetAssemblyIdentityFromFile || !g_pfnGetIdentityAuthority) {
        printf("Error: Cannot get required APIs from fusion.dll!\n");
        goto Exit;
    }

    bRC = true;

Exit:
    return bRC;
}

void Shutdown()
{
    if(g_pUnk) {
        g_pUnk->Release();
        g_pUnk = NULL;
    }
}

void Usage()
{
    printf("ShowName: A tool to show the display name of a given assembly.\n\n");
    printf("Usage: ShowName AsmFilePath\n");
    printf("\n");
}

int _cdecl wmain(int argc, LPCWSTR argv[])
{
    int     iResult = 1;
    IUnknown            *pUnk = NULL;
    IReferenceIdentity  *pRef = NULL;
    IIdentityAuthority  *pAuth = NULL;
    WCHAR               Buffer[1024];
    DWORD               dwSize = sizeof(Buffer)/sizeof(WCHAR);
    HRESULT             hr = S_OK;  

    if(argc != 2) {
        Usage();
        goto Exit;
    }

    if(!Init()) {
        printf("Failure initializing ShowName.\n");
        goto Exit;
    }

    hr = g_pfnGetAssemblyIdentityFromFile(argv[1], __uuidof(IReferenceIdentity), &pUnk);
    if (FAILED(hr)) {
        printf("GetAssemblyIdentityFromFile failed with hr = 0x%x", hr);
        goto Exit;
    }

    hr = pUnk->QueryInterface(__uuidof(IReferenceIdentity), (void**)&pRef);
    if (FAILED(hr)) {
        goto Exit;
    }

    hr = g_pfnGetIdentityAuthority(&pAuth);
    if (FAILED(hr)) {
        goto Exit;
    }

    hr = pAuth->ReferenceToTextBuffer(0, pRef, dwSize, Buffer, &dwSize);
    if (FAILED(hr)) {
        printf("ReferenceToTextBuffer failed with hr = 0x%x.\n", hr);
        goto Exit;
    }

    printf("Assembly Identity of %ws is:\n", argv[1]);
    printf("%ws\n", Buffer);

    iResult = 0;

Exit:

    Shutdown();

    if (pUnk) {
        pUnk->Release();
    }

    if (pRef) {
        pRef->Release();
    }

   if (pAuth) {
      pAuth->Release();
   }

    return iResult;
}

Here is some sample output:

C:>showname C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\system.dll
Assembly Identity of C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\system.dll is:
System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL