9

Visual C ++6.0はWindows8ではサポートされていませんが、Visual C++6.0でコンパイルする必要のあるレガシーアプリがいくつかあります。:-(

[データアクセス]->[オプションの変更]->[ADO、RDS、およびOLE DBプロバイダー]のチェックを外すことで、Windows8にVisualC++6.0をインストールできます。このSU質問このスレッドを参照してください。また、後でSP6をインストールする必要があります。

Visual C ++ 6.0は1台のコンピューターで完全に動作しますが、他の2台はデバッガーを使用できません。同じハードウェア、同じバージョンのWindows、同じインストールを行う人、同じプロジェクト。違いがあるに違いない...

問題のあるコンピューターでは、ブレークポイントを設定すると、デバッガーがIDEに侵入しますが、ステップを実行しようとすると、EXENAME.EXE(OLE32.DLL)の未処理の例外でコードがクラッシュします:0xC0000005 :アクセス違反

Walter OneyはMSDNフォーラムでまったく同じ問題を報告していますが、VC ++ 6.0がサポートされていないため、解決策はありません。

Visual C ++ 6.0が1台のWin8コンピューターで動作しているので、明らかにそれを行う方法があります。違いが何であるかについてのアイデアはありますか?

4

5 に答える 5

6

OLE RPC デバッグ (ツール / オプション / デバッグ) をオフにするとうまくいきます (Windows 8 Pro 64 ビット、Visual C++ 6.0 SP6)。このソリューションは、前述の MSDN フォーラム スレッド内で (後で) 提案されました。

于 2013-08-22T08:05:11.833 に答える
2

最終的に、VS 6 を Win 8 と Win 10 で動作させることができました。基本的な手順は次のとおりです。

  1. \Windows に msjava.dll という名前のダミー ファイルを作成します。(例: "echo >msjava.dll") この手順がないと、VS 6 インストーラーはうまく機能しません。

  2. VS 6 と SP 6 をインストールします。

  3. MSDEV.EXE の名前を、MSDEVQ.EXE などの別の名前に変更します。

  4. フォールト トレラントなヒープ shim を除外する MSDEVQ の互換性データベースを作成します。このステップがないと、HeapAlloc などを多用するプログラムのデバッグは、非常に遅くなります。

  5. デバッグの場合、OLE32 への呼び出しが発生する前に、ブレークポイントがトリップされることを確認してください。メイン プログラムまたは (MFC アプリの場合) InitInstance 関数の早い段階で、次のヘッダーを含めます。

X64DebugHack.h:

#ifdef _DEBUG
// In order to be able to debug this application on x64, we need to single
// step across at least one statement before ole32.dll gets loaded. So
// always leave this breakpoint in place.

requiredbreakpoint:
    int junkola = 42;

    // Check to see that there was a breakpoint...

    PUCHAR pjunk;
    _asm lea eax, requiredbreakpoint
    _asm mov pjunk, eax

    if (*pjunk != 0xCC)
        AfxMessageBox("Required breakpoint was not set prior to loading OLE32.DLL -- single stepping will not be possible during this debugging session.", MB_OK | MB_ICONHAND, 0);

    LoadLibrary("OLE32");
#endif
  1. 「デバッグの停止」ボタンを提供する拡張 DLL を記述します。拡張機能は、Win64 と Win32 では異なるハンドル タイプを持つデバッグ ハンドルを検索して破棄する必要があります。拡張機能を記述するメカニズムは、このフォーラムの範囲を超えていますが、実際の作業を行うコードは次のとおりです。

CCommands::HelpAssistantKill:

typedef LONG NTSTATUS;
#define NT_SUCCESS(Status)  (((NTSTATUS)(Status)) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004L)

enum SYSTEM_INFORMATION_CLASS {
    SystemHandleInformation = 16,
    };

typedef NTSTATUS(NTAPI *PNTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);

typedef struct _SYSTEM_HANDLE_INFORMATION {
    ULONG ProcessId;
    UCHAR ObjectTypeNumber;
    UCHAR Flags;
    USHORT Handle;
    PVOID Object;
    ACCESS_MASK GrantedAccess;
    } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef struct _SYSTEM_HANDLE_INFORMATION_DATA {
    ULONG HandleCount;
    SYSTEM_HANDLE_INFORMATION HandleInformation[1];
    } SYSTEM_HANDLE_INFORMATION_DATA, *PSYSTEM_HANDLE_INFORMATION_DATA;

#define HANDLE_TYPE_DEBUG_OBJECT 11     // correct value for Win8 x64

STDMETHODIMP CCommands::HelpAssistantKill()
    {                           // CCommands::HelpAssistantKill
    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    BOOL didit = FALSE;
    HMODULE hDll = NULL;
    PSYSTEM_HANDLE_INFORMATION_DATA phi = NULL;

    do  {                       // do once
        HRESULT hr;

        // Locate NtQuerySystemInformation within NTDLL.DLL

        hDll = LoadLibrary("NTDLL");
        if (!hDll)
            break;

        PNTQUERYSYSTEMINFORMATION NtQuerySystemInformation = (PNTQUERYSYSTEMINFORMATION) GetProcAddress(hDll, "NtQuerySystemInformation");
        if (!NtQuerySystemInformation)
            break;

        // Do an initial query to get the number of handles presently open in the system.
        // This is a large number. The returned length value is meaningless for this query.

        SYSTEM_HANDLE_INFORMATION_DATA hid;
        DWORD junk;
        NTSTATUS status = (*NtQuerySystemInformation)(SystemHandleInformation, &hid, sizeof(hid), &junk);
        if (!NT_SUCCESS(status) && status != STATUS_INFO_LENGTH_MISMATCH)
            break;

        ULONG length = sizeof(SYSTEM_HANDLE_INFORMATION_DATA) + (hid.HandleCount - 1) * sizeof(SYSTEM_HANDLE_INFORMATION);
        phi = (PSYSTEM_HANDLE_INFORMATION_DATA) new UCHAR[length];
        if (!phi)
            break;

        // Get a list of all handles open in the system

        status = (*NtQuerySystemInformation)(SystemHandleInformation, phi, length, &junk);
        if (!NT_SUCCESS(status))
            break;

        // Find and close any debug objects that are open in this instance of Visual Studio.

        DWORD pid = GetCurrentProcessId();
        ULONG ihandle;
        for (ihandle = 0; ihandle < hid.HandleCount; ++ihandle)
            {                   // for each open handle
            PSYSTEM_HANDLE_INFORMATION p = phi->HandleInformation + ihandle;
            if (p->ProcessId != pid || p->ObjectTypeNumber != HANDLE_TYPE_DEBUG_OBJECT)
                continue;

            if (CloseHandle((HANDLE) p->Handle))
                didit = TRUE;           
            }                   // for each open handle

        // Instruct DevStudio to stop

        BSTR bsStopDebugging = SysAllocString(L"DebugStopDebugging");
        if (!bsStopDebugging)
            break;

        hr = m_pApplication->ExecuteCommand(bsStopDebugging);
        SysFreeString(bsStopDebugging);
        if (hr != 0)
            break;
        }                       // do once
    while (FALSE);

    if (phi)
        delete[] phi;

    if (hDll)
        FreeLibrary(hDll);

    if (!didit)
        {                       // didn't do anything
        MessageBox(NULL, "Unable to find and close any debug object handles", "HelpAssistant", MB_OK | MB_ICONINFORMATION);
        }                       // didn't do anything

    return S_OK;
    }                           // CCommands::HelpAssistantKill

これはかなり勇敢な取り組みのように感じましたが、VS 6 でビルドされた約 100 万行のコードを作業し続ける必要がありました。VS 2015 用の実行可能なマクロ プロセッサを自分で作成したので、このアプリケーションの変換を行うことができます。

于 2015-09-22T07:54:28.547 に答える
1

1 つのしわ - Windows 8.1 の Visual C++ 6.0 デバッガーでまったく同じ問題が発生しました。しかし、上記の回答で説明されているツール/オプション/デバッグ オプションの下に RPC デバッグ オプションが見つかりませんでした。代わりに、レジストリ エディターに移動して、上記で参照した同じ MSDN スレッドに記載されている RPC Debug キーを削除する必要がありました (6.0 をインストールする前に、Microsoft Visual Studio の新しいバージョンを既にインストールしていたため、そこにあった可能性があります)。以前のポスターのおかげで、デバッガーは今ではうまく機能します!

于 2014-12-10T13:20:57.093 に答える