OCXAfxOleRegisterTypeLibがエラー0x80040200で失敗する

サラ・ワインバーガー

OCXライブラリをVS2010 / Win7からVS2019 / Win10にアップグレードしました。プロジェクトはビルドされRegSvr32.exeますが、管理者特権のコマンドプロンプトから使用しようとすると、エラー0x0040200が表示されます。少しデバッグを行いましたが、問題のある呼び出しはへの呼び出しAfxOleRegisterTypeLibです。

RegSvr32.exeOCXエラー0x80040200

はい、「dllの近くにtlbファイルがない」と述べているこのSOの記事を見ました。その他の検索状態では、管理コマンドプロンプトから実行します。

OCXコントロールの近くにTLBがありません。を使用して作成しようとするとtlbexp.exe、次のエラーが発生します。

TlbExp:エラーTX0000:ファイルまたはアセンブリ 'file:/// C:\ pathto.ocx'またはその依存関係の1つを読み込めませんでした。モジュールには、アセンブリマニフェストが含まれている必要がありました。

TlbExpコマンドライン(すべてのcmd.exeの管理者として実行を使用):

"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools\x64\tlbexp.exe" /VERBOSE "<path to OCX file>" /out:"<path to .tlb output file>"

ダウンロードResource Tunerしたところ、マニフェストがうまく表示されています。マニフェストにはTLB情報がありません。

OCXファイルのマニフェスト

OCXマニフェストには、必要なTlbExp情報取得するのに役立つ何かが必要だと思います。考えてみてください。

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="DriveOps.ocx"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!-- Windows 7 -->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
      <!-- Windows 8 -->
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
      <!-- Windows 8.1 -->
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
      <!-- Windows 10 -->
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
    </application>
  </compatibility>
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
        <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>
</assembly>

私はDepends64(別名Dependency Walker 64-bit)を使用しましたが、不足しているコンポーネントDLLはありません。RegSvr32.exeと同様に、それらすべてが適切に検出されます。

64ビットOCXのDependencyWalker 64出力(デバッグバージョン)

OCXファイルをC:\ Windows \ System32に配置しても役に立ちません。

DLLを見ている人なら誰でも、これらの同じDLLはWin7ボックスで正常に機能します。Windows以外のDLLに関する詳細情報は次のとおりです。

  • PlxApi720_x64.dll: PLX v7.2 API (The Broadcom PLX chip is a PCIe switch (think USB/network switch, just w/PCIe lanes)
  • LSIDirectAccess.dll: The LSI API is a self-contained DLL that allows the software to talk to the LSI HBA RAID adapter
  • Ipp*.dll: The Ipp prefix are the DLLs used by the Intel Code Composer Studio redistribution (x64) files, here version 2011, an older one that needs to be updated to the latest and greatest, not to mention now free API. These are all in the System32 folder.

Here is the code:

// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void)
{
    AFX_MANAGE_STATE(_afxModuleAddrThis);

    if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
        return ResultFromScode(SELFREG_E_TYPELIB);           // <- failure line, through debugging

    if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
        return ResultFromScode(SELFREG_E_CLASS);

    return NOERROR;
}

The Intel Code Composer Studio 2011 files are in the C:\Windows\System32 directory, just like on the Win7 box.

For what it is worth, TlbExp fails on the Win7 box too, just it registers, which is probably why the UI can add the control. As I recall, I once replaced the OCX on the Win7 project and VS2010 automatically created the TLB and prefixed Ax in front, but that was a couple of years ago, so my memory may not be the most accurate. Attempting to add the OCX to the UI (.Net WinForms) fails miserably and just says could not be added.

The OCX does use the latest platform tool set (Visual Studio 2019 (v142)).

OCXプロパティページ

A comment for developer newbies, regasm.exe is for .Net Assemblies. RegSvr32.exe is for ActiveX Controls (OCX/DLL), which is what I have. RegSvr32 is for dynamically loaded modules, hence the DllRegister entry point.

Thoughts?

Notes From Further Testing

  1. (Saturday 9/21/2019) When I upgraded, I created an empty C++ DLL project and then added all the files, changing the target extension to OCX going through the old project settings and when reasonable aligning them to the new project file wanting to keep things the same. I wanted to do a test and see what happens with a brand new OCX project. I saw that there was such a thing as "MFC ActiveX Control" for a project type in VS2019. I created that and saw that I got different base files, but more importantly RegSvr32.exe works. That means that either the mistake was the initial project file, so I need to import to a clean project or import piece by piece, if that is possible, and see where things break.

  2. (Saturday 9/21/2019) The new test project did not come with a manifest file and TlbExp.exe failed with the same error message like my real project. I went to add new item and saw "Package Manifest". That manifest file, though still produces the same TlbExp.exe error, looks quite different from the application manifest file from above. I created yet another new MFC ActiveX Control project and added in the manifest from above just changing names and saw that the project refused to build throwing 1) Error c1010001 Values of attribute "level" not equal in different manifest snippets. and 2) LNK1327 failure during running mt.exe. That tells me that the original Win7 project and my Win10 project files probably have some error in it, otherwise VS should have thrown these errors to me. That does not answer why even on the test project TlbExp.exe fails. Maybe some attributes in the manifest are required. I just left the defaults.

Package Manifest (It is the first time that I ever saw one of these. I always saw the app.manifest kind.)

<?xml version="1.0" encoding="utf-8"?>
<!-- TODO: Make sure to set the Package attributes -->
<Package xmlns="urn:Microsoft.WindowsPhone/PackageSchema.v8.00"
  Owner=""
  OwnerType="OEM"
  Platform=""
  Component=""
  SubComponent="Package"
  ReleaseType="Test" >

  <Components>
    <Driver InfSource="$(_RELEASEDIR)$(TARGETNAME).inf">
      <Reference Source="$(_RELEASEDIR)$(TARGETNAME)$(TARGETEXT)" />
      <Files>
        <!-- For kernel mode drivers, $(DRIVER_DEST) evaluates to "drivers" by default -->
        <!-- For user mode drivers, $(DRIVER_DEST) evaluates to "drivers\umdf" by default -->
        <File Source="$(_RELEASEDIR)$(TARGETNAME)$(TARGETEXT)" DestinationDir="$(runtime.system32)\$(DRIVER_DEST)" />
      </Files>
    </Driver>

  </Components>
</Package>
  1. This article has an interesting approach, namely create a C++ DLL and then call LoadLibrary(dll) and after that GetProcAddress(module, "DllRegisterServer") to see which one fails. Well, in my case the both functions succeed. That means that the author missed one other failure branch and these two API calls are not the only thing that RegSvr32.exe does.
Sarah Weinberger

Though I am still not at the end of the road, as I have aximp.exe / tlbimp.exe issues on the OCX, I found the problem that prevented me from registering the ActiveX control, which was the question here.

The answer is the GUID in the main CPP file:

(I am giving my research, as I could not find anyone explaining how RegSvr32.exe works and what it does. I wanted to share in hopes that it helps others.)

const GUID CDECL _tlid = { 0xFE5C7D88,0xD53C,0x4977,{0xBA,0x56,0x4B,0xF3,0x02,0x0A,0x5D,0x8A} };

which gets used in the main registration function STDAPI DllRegisterServer(void) must match the GUID present in the IDL:

[uuid(FE5C7D88-D53C-4977-BA56-4BF3020A5D8A), version(1.0),
helpfile("DriveOps.hlp"),
helpstring("DriveOps ActiveX Control module"),
control]
library DriveOpsLib
{
...
}

I had 2 different values, hence the failure.

Here is the methodology and research that I used to find the problem, but first I will state the registration function, as that is key again.

STDAPI DllRegisterServer(void)
{
    AFX_MANAGE_STATE(_afxModuleAddrThis);

    HINSTANCE hiTypeLib = AfxGetInstanceHandle();

    if (!AfxOleRegisterTypeLib(hiTypeLib, _tlid))
        return ResultFromScode(SELFREG_E_TYPELIB);

    if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
        return ResultFromScode(SELFREG_E_CLASS);

    return NOERROR;
}

The failure was at this line, as I believe was mentioned in the question.

if (!AfxOleRegisterTypeLib(hiTypeLib, _tlid))

I had already found the source code for RegSvr32.exe on the internet. It was part of Microsoft GitHub sources located in VCSamples-master.

Direct Link to RegSvr32.exe: here

Direct Link to download zip: here

The code was a sort of dead end, as it told me what should have been obvious, namely that utility called the DllRegisterServer entry point of a DLL to do all the work. I should have known that, but, well, I had to see it to make sense.

Using procmon.exe, did not shed any light and the various calls to the registry was like reading a foreign language, not helpful.

Here I drew a blank until it occurred to me to get the source code for AfxOleRegisterTypeLib, as that what was failing. I wanted to see what the heck that thing did and what was at line 113 of source file ctlreg.cpp.

I was still thinking on the comment of procmon and a registry issue, but I figured that the code will tell me which one. It took me a bit of research, but I found the code. I love Microsoft sharing code. Their error messages are not helpful, but being able to actually see what they were trying to do so totally helps.

Here is the code:

BOOL AFXAPI AfxOleRegisterTypeLib(HINSTANCE hInstance, REFGUID tlid,
    LPCTSTR pszFileName, LPCTSTR pszHelpDir)
{
    USES_CONVERSION;

    BOOL bSuccess = FALSE;
    CString strPathName;
    TCHAR *szPathName = strPathName.GetBuffer(_MAX_PATH);
    ::GetModuleFileName(hInstance, szPathName, _MAX_PATH);
    strPathName.ReleaseBuffer();
    LPTYPELIB ptlib = NULL;

    // If a filename was specified, replace final component of path with it.
    if (pszFileName != NULL)
    {
        int iBackslash = strPathName.ReverseFind('\\');
        if (iBackslash != -1)
            strPathName = strPathName.Left(iBackslash+1);
        strPathName += pszFileName;
    }

    if (SUCCEEDED(LoadTypeLib(T2COLE(strPathName), &ptlib)))
    {
        ASSERT_POINTER(ptlib, ITypeLib);

        LPTLIBATTR pAttr;
        GUID tlidActual = GUID_NULL;

        if (SUCCEEDED(ptlib->GetLibAttr(&pAttr)))
        {
            ASSERT_POINTER(pAttr, TLIBATTR);
            tlidActual = pAttr->guid;
            ptlib->ReleaseTLibAttr(pAttr);
        }

        // Check that the guid of the loaded type library matches
        // the tlid parameter.
        ASSERT(IsEqualGUID(tlid, tlidActual));

        if (IsEqualGUID(tlid, tlidActual))
        {
            // Register the type library.
            if (SUCCEEDED(RegisterTypeLib(ptlib, T2OLE((LPTSTR)(LPCTSTR)strPathName), T2OLE((LPTSTR)pszHelpDir))))
                bSuccess = TRUE;
        }

        RELEASE(ptlib);
    }
    else
    {
        TRACE1("Warning: Could not load type library from %s\n", (LPCTSTR)strPathName);
    }

    return bSuccess;
}

I kept receiving an ASSERT, so although line 113 did was on a non-code line, the actual failure was obvious. I knew that I did not fail out on the ASSERT_POINTER, as that error message is different, which meant that I failed at:

        ASSERT(IsEqualGUID(tlid, tlidActual));

I looked at the code in detail as well as the entry arguments. I decided to copy and paste this function contents into the real registration code in my OCX to gain further visibility while debugging. I wanted to see the values.

Sure enough, I saw 2 different GUID values, one from the top, my _tlid, and the one returned from the instance handle. I took out my handy-dandy TextPad text editor, though Visual Studio has a Find in Files, but TextPad is so much easier to use. That led to one other instance in the entire solution, namely in DriveOps.idl. That file up until that moment meant nothing to me, but suddenly I saw that the GUID here was the one that RegSvr32.exe pulled from the instance handle.

I unified the IDs, rebuilt, and now RegSvr32.exe no longer complains. Yeah, since I got the code, it had no choice but to register. That it does not modify the registry is a different story and problem from what I can tell, but that is another question. RegSvr32.exe now registers without complaint.

(はい、私はまだ持っているtlbimp.exeaximp.exeと私に私のOCXプロジェクトを追加するWinFormsプロジェクトの問題が、私はこの事をなめ、その過程で何かを学んしまった。私は、行番号の差は、いくつかは、Microsoftがヘッダーで行われた変更のいずれかであってもよい方法を推測します、機能は同じように見えます。)

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

OCXAfxOleRegisterTypeLibがエラー0x80040200で失敗する

分類Dev

DirectCompute CreateBufferがエラー0x80070057(E_INVALIDARG)で失敗する

分類Dev

Windows7のエラーコード0x80248015でWindowsUpdateが失敗するのはなぜですか?

分類Dev

クリーンなWindows10のインストールがSSDで失敗し、エラーコード0x8007025Dで失敗する

分類Dev

VistaSP2へのIE9の統合がエラー0x8007000eで失敗する

分類Dev

vue-cli-serviceビルドが0エラーで失敗する

分類Dev

IE https CORS XHRリクエストがScript7002で失敗する:XMLHttpRequest:ネットワークエラー0x2eff

分類Dev

修正:WslRegisterDistributionがエラーで失敗しました:0x80370102

分類Dev

SwiftKueryPostgresql接続がエラー「スレッド1:EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP、subcode = 0x0)」で失敗する

分類Dev

WSL2 / Ubuntu 20.04 (Windows ビルド 2004) (ブートキャンプ) のセットアップがエラー コード 0x80370102 で失敗する

分類Dev

GoConveyテストがエラーコード0で失敗するのはなぜですか?

分類Dev

pythonsetup.pyがsslエラーでosxで失敗する

分類Dev

pythonsetup.pyがsslエラーでosxで失敗する

分類Dev

AzureCDNのパージがエラーInvalidResourceで失敗する "

分類Dev

az cli create webappがResourceNotFoundエラーで失敗する

分類Dev

iOSSFHFKeychainUtilsがエラー-25308で*時々*失敗するerrSecInteractionNotAllowed

分類Dev

相互証明書認証がエラー403.16で失敗する

分類Dev

Google Cloud Storage TransferServiceがUNKNOWNエラーで失敗する

分類Dev

エラーASP0177:8007007eCreateObjectがCOMDLLで失敗する

分類Dev

Gulpuglifyがjs解析エラーで失敗する

分類Dev

Rstudiopdfニットが「EnvironmentShadedundefined」エラーで失敗する

分類Dev

Composerが「npm-signature」エラーで更新に失敗する

分類Dev

brewの更新が「Permissiondenied」エラーで失敗する

分類Dev

FirebaseServeコマンドがエラー404で失敗する

分類Dev

rename_at(dplyr)がエラーで失敗する

分類Dev

venv / bin / python -m jupyternbconvertがエラーで失敗する

分類Dev

npm install -g @ angular / cliが構文エラーで失敗する

分類Dev

SpotifySessionManagerがエラー「invalid_grant」で継続的に失敗する

分類Dev

Symfonyの更新がYAMLエラーで失敗する

Related 関連記事

  1. 1

    OCXAfxOleRegisterTypeLibがエラー0x80040200で失敗する

  2. 2

    DirectCompute CreateBufferがエラー0x80070057(E_INVALIDARG)で失敗する

  3. 3

    Windows7のエラーコード0x80248015でWindowsUpdateが失敗するのはなぜですか?

  4. 4

    クリーンなWindows10のインストールがSSDで失敗し、エラーコード0x8007025Dで失敗する

  5. 5

    VistaSP2へのIE9の統合がエラー0x8007000eで失敗する

  6. 6

    vue-cli-serviceビルドが0エラーで失敗する

  7. 7

    IE https CORS XHRリクエストがScript7002で失敗する:XMLHttpRequest:ネットワークエラー0x2eff

  8. 8

    修正:WslRegisterDistributionがエラーで失敗しました:0x80370102

  9. 9

    SwiftKueryPostgresql接続がエラー「スレッド1:EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP、subcode = 0x0)」で失敗する

  10. 10

    WSL2 / Ubuntu 20.04 (Windows ビルド 2004) (ブートキャンプ) のセットアップがエラー コード 0x80370102 で失敗する

  11. 11

    GoConveyテストがエラーコード0で失敗するのはなぜですか?

  12. 12

    pythonsetup.pyがsslエラーでosxで失敗する

  13. 13

    pythonsetup.pyがsslエラーでosxで失敗する

  14. 14

    AzureCDNのパージがエラーInvalidResourceで失敗する "

  15. 15

    az cli create webappがResourceNotFoundエラーで失敗する

  16. 16

    iOSSFHFKeychainUtilsがエラー-25308で*時々*失敗するerrSecInteractionNotAllowed

  17. 17

    相互証明書認証がエラー403.16で失敗する

  18. 18

    Google Cloud Storage TransferServiceがUNKNOWNエラーで失敗する

  19. 19

    エラーASP0177:8007007eCreateObjectがCOMDLLで失敗する

  20. 20

    Gulpuglifyがjs解析エラーで失敗する

  21. 21

    Rstudiopdfニットが「EnvironmentShadedundefined」エラーで失敗する

  22. 22

    Composerが「npm-signature」エラーで更新に失敗する

  23. 23

    brewの更新が「Permissiondenied」エラーで失敗する

  24. 24

    FirebaseServeコマンドがエラー404で失敗する

  25. 25

    rename_at(dplyr)がエラーで失敗する

  26. 26

    venv / bin / python -m jupyternbconvertがエラーで失敗する

  27. 27

    npm install -g @ angular / cliが構文エラーで失敗する

  28. 28

    SpotifySessionManagerがエラー「invalid_grant」で継続的に失敗する

  29. 29

    Symfonyの更新がYAMLエラーで失敗する

ホットタグ

アーカイブ