2012-02-06 10 views
3

カスタムAppDomain Managerを持つ.net clrとストアを持つAssemblyManagerをホストするアプリケーションがあります。CLRホストからProvideAssemblyによってAppDomainManagerをロードできますか?

AppDomainManagerを持つアセンブリが実行可能ファイルと同じディレクトリにあるdllである場合、これはすべて正常に動作します。

実行したいのは、マネージャーアセンブリを実行可能ファイルに埋め込むことです。私がこのProvideAssemblyを正しい厳密な名前で呼び出すと、アセンブリバイトを含むストリームが返されますが、ICLRRuntimeHost-> Start()は、型をロードできないことを示すエラーを返します。

すべてのアセンブリバインディングの詳細は、この構成はサポートされている場合、誰もが知っているんさなど

私の質問に一致しますか? AppDomainManagersアセンブリをファイルからではなくこの方法で読み込むことはできますか?


現在、IHostAssemblyManagerをCLRにのみ提供しています。 (持っているが、デバッガで通じステップと、何も失敗していない)、マップから

#define ASSEMBLY L"MscoreeIntegration, Version=1.0.0.0, PublicKeyToken=a0c02a181a22f567, Culture=neutral" 
#define MANAGER L"MscoreeIntegration.Manager" 

m_clrcontrol->SetAppDomainManagerType(ASSEMBLY, MANAGER); 

検索バインディングアイデンティティ格納されたデータのIStreamのを返しますとコール。

HRESULT STDMETHODCALLTYPE AssemblyManager::GetNonHostStoreAssemblies(ICLRAssemblyReferenceList **ppReferenceList){ 
    *ppReferenceList = NULL; 
    return S_OK; 
} 

HRESULT STDMETHODCALLTYPE AssemblyManager::GetAssemblyStore(IHostAssemblyStore **ppAssemblyStore){ 
    *ppAssemblyStore = m_impl->m_store; 
    return S_OK; 
} 

HRESULT STDMETHODCALLTYPE AssemblyStore::ProvideAssembly(AssemblyBindInfo *pBindInfo, UINT64 *pAssemblyId, UINT64 *pContext, IStream **ppStmAssemblyImage, IStream **ppStmPDB){ 
    map<wstring,Data*>::iterator find = m_impl->m_assemblies.find(pBindInfo->lpPostPolicyIdentity); 
    if(find!=m_impl->m_assemblies.end()){ 
     *pAssemblyId = find->second->m_id; 

     HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, find->second->m_cbLength); 
     LPVOID pData = ::GlobalLock(hMem); 
     memcpy(pData, find->second->m_pData, find->second->m_cbLength); 
     ::GlobalUnlock(hMem); 

     HRESULT hr = ::CreateStreamOnHGlobal(hMem, FALSE, ppStmAssemblyImage); 

     *pContext = 0; 
     *ppStmPDB = NULL; 
     return S_OK; 
    } 

    return 0x80070002; //COR_E_FILENOTFOUND; 
} 

は私が結合アイデンティティそうのように取得する:ハンスが言ったように、あなたはすでにあなたが必要なすべてを持っている

void AddAssembly(AssemblyStore *store, ICLRAssemblyIdentityManager *ident, const char* filename){ 
    int length = 0; 
    const char *buffer = LoadData(filename, length); 
    IStream *stream = GetStream(buffer, length); 
    if(!stream){ return; } 

    DWORD cbBuffer = 0; 
    HRESULT hr = ident->GetBindingIdentityFromStream(stream, 0, NULL, &cbBuffer); 

    wchar_t *bind = (wchar_t*)malloc(cbBuffer*sizeof(wchar_t)); 
    stream = GetStream(buffer, length); 
    hr = ident->GetBindingIdentityFromStream(stream, 0, bind, &cbBuffer); 

    BOOL strong; 
    hr = ident->IsStronglyNamed(bind, &strong); 
    if(!strong){ 
     printf("NOT STRONG: %S\n", bind); 
    } 

    store->AddAssembly(bind, (BYTE*)buffer, length); 
} 
+1

はい、これはサポートされています。 –

+0

こんにちは、コメントをありがとう、私はあなたが私のホストが失敗する理由を解決するために私を指すことができる任意のドキュメント/ページがありますか?私はMSのCLRを参照してオンラインドキュメントとMSの本をホスティング "CLRのカスタマイズ"私は何か愚かなことをしている必要があります! – BafflingTangent

+0

まだ持っていないものはありません。あなたの問題をよりよく説明するまで、誰もあなたを助けることはできません。コードスニペットは最小要件です。 –

答えて

1

。上記の本には、AppDomainManagerクラスを含むアセンブリがホストによってOLE複合ファイルから取り出される既成の例があります。

私も同様のことをしていますので、動作確認できます。非ホストアセンブリのリストを生成するときは、3つの点に注意する必要があります。

  • 正しく構築する方法がわからない場合は、CLRに処理させる(NULLを返す)ようにしてください。 pAssemblyIdを返すと決して解像度はGAC -> Host -> other Fusion search paths
  • になります。それを教えてください、しかしそれは非常に..特有の振る舞いをもたらします。
  • ファイルをIStreamに読み込みます。個人的には、Win32 APIを使用してIStreamを実装するFileStreamのunamangedクラスを作成しました。この目的のために書かれていないコード(またはシェルAPIのような "奇妙な"ものへのリンク)に頼るよりも良い方法です。
関連する問題