9

Windows 8 不支持 Visual C++ 6.0,但我们有几个遗留应用程序仍需要使用 Visual C++ 6.0 进行编译。:-(

通过取消选中Data Access -> Change Options -> ADO, RDS and OLE DB Providers可以在 Windows 8 上安装 Visual C++ 6.0 。请参阅此 SU 问题此线程。之后还需要安装 SP6。

Visual C++ 6.0 在一台计算机上完美运行,但另外两台无法使用调试器。相同的硬件,相同的 Windows 版本,相同的安装人员,相同的项目。应该是有区别的...

在有问题的计算机上,您可以设置断点,调试器将中断 IDE,但是当您尝试执行单步执行、单步执行或运行代码时,代码将因 EXENAME.EXE (OLE32.DLL) 中的未处理异常而崩溃:0xC0000005 : 访问冲突

Walter Oney在 MSDN 论坛上报告了完全相同的问题,但他们没有解决方案,因为不支持 VC++ 6.0。

由于我们在一台 Win8 计算机上运行 Visual C++ 6.0,显然有办法做到这一点。关于可能有什么不同的任何想法?

4

5 回答 5

6

关闭 OLE RPC 调试(工具/选项/调试)对我有用(Windows 8 Pro 64 位,带有 SP6 的 Visual C++ 6.0)。(稍后)在上述 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. 为排除容错堆填充程序的 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 上构建了大约一百万行代码,我必须继续工作。现在我已经为 VS 2015 构建了一个可行的宏处理器,我可以对这个应用程序进行转换。

于 2015-09-22T07:54:28.547 回答
1

一个问题 - 我在 Windows 8.1 上使用 Visual C++ 6.0 调试器时遇到了同样的问题。但是我在上面的答案中描述的工具/选项/调试选项下找不到 RPC 调试选项。相反,我不得不进入注册表编辑器并删除上面引用的同一 MSDN 线程中提到的 RPC 调试键(可能是因为我在安装 6.0 之前已经安装了更高版本的 Microsoft Visual Studio)。调试器现在工作得很好,感谢以前的海报!

于 2014-12-10T13:20:57.093 回答
0

以上答案都不适合我。

该站点的解决方案解决了我的问题。

重新注册 ole32.dll 文件并检查它是否有帮助。

  1. 单击开始,在开始搜索中键入 cmd。

  2. 右键单击cmd,然后单击以管理员身份运行。

  3. 在命令提示符下,键入以下命令并在每个命令后按 Enter。

    takeown /f ole32.dll

    regsvr32 ole32.dll

  4. 运行以上两个命令后关闭命令提示符。

尝试运行应用程序并检查问题是否仍然存在。

于 2017-01-18T03:47:09.060 回答
0

该问题是由于不兼容的“ADO、RDS 和 OLE DB 提供程序”与 Visual C++ 6.0 一起提供的。

请按照下面提到的步骤禁用 ADO、RDS 和 OLE DB 提供程序并安装 Visual C++ 6.0 –

1) 像往常一样开始安装。

2) 当安装程序询问安装类型时,单击自定义安装。

3) 单击可用项目中的数据访问,然后单击“更改选项”。

4) 在新窗口中取消选择“ADO、RDS 和 OLE DB Providers”并单击“确定”(忽略警告)。

5) 点击继续安装。

6) 安装程序不会在“更新组件”期间冻结,并且会成功安装。

7) 现在安装服务包“Vs6sp6”,它也将安装成功。

于 2015-10-23T10:28:33.680 回答