Windows 8 上的 Visual C++ 6.0

Posted

技术标签:

【中文标题】Windows 8 上的 Visual C++ 6.0【英文标题】:Visual C++ 6.0 on Windows 8 【发布时间】:2013-01-24 19:12:40 【问题描述】:

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

可以通过取消选中数据访问 -> 更改选项 -> ADO、RDS 和 OLE DB 提供程序,在 Windows 8 上安装 Visual C++ 6.0。请参阅 this SU-question 和 this thread。之后还需要安装 SP6。

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

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

Walter Oney 报告了exact same problem on MSDN forums,但他们没有解决方案,因为不支持 VC++ 6.0。

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

【问题讨论】:

我在论坛上读到的一个建议(不记得在哪里)是确保 Visual Studio 6 是机器上第一次安装 Visual Studio,然后安装您可能使用的较新版本。我不确定这是否完全正确,但当我开始使用干净的 Win 8 VM 时它对我有用 能否使用支持 Windows 版本的 VM?我们使用几个 BCB 遗留应用程序成功地做到了这一点。有时,嗯,困难,当需要某些硬件访问或增强的图形功能时...... - 刚刚意识到,这是一个较旧的问题,已显示为“活动”,无论如何,提示可能会有所帮助,因为问题是' t 标记为已回答。 【参考方案1】:

关闭 OLE RPC 调试(工具/选项/调试)对我有用(Windows 8 Pro 64 位,Visual C++ 6.0 with SP6)。 (稍后)在上述 MSDN 论坛帖子中建议了此解决方案。

【讨论】:

“OLE RPC 调试”是第二行倒数第二项。它已经变灰了。选择它上面的选项(“及时调试”)将启用它,然后您可以取消选中“OLE RPC 调试”。这对我有用!谢谢大家!!!【参考方案2】:

我最终能够让 VS 6 在 Win 8 和 Win 10 上运行。基本步骤如下:

    在 \Windows 中创建一个名为 msjava.dll 的虚拟文件。 (例如,“echo >msjava.dll”)如果没有这一步,VS 6 安装程序就不能走得很远。

    安装 VS 6 和 SP 6。

    将 MSDEV.EXE 重命名为其他名称,例如 MSDEVQ.EXE。

    为排除容错堆填充程序的 MSDEVQ 创建兼容性数据库。如果没有这一步,调试大量使用 HeapAlloc 等的程序会非常缓慢。

    对于调试,请确保在对 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
    编写一个提供“停止调试”按钮的扩展 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 构建了一个可行的宏处理器,我可以对这个应用程序进行转换。

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

此问题是由于 Visual C++ 6.0 附带的“ADO、RDS 和 OLE DB 提供程序”不兼容所致。

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

1) 照常开始安装。

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

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

4) 在新窗口中取消选择“ADO, RDS and OLE DB Providers”并点击OK(忽略警告)。

5) 点击继续安装。

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

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

【讨论】:

【参考方案5】:

以上答案都不适合我。

this site 的解决方案解决了我的问题。

重新注册ole32.dll文件,看看是否有帮助。

    点击开始,在开始搜索中输入cmd。

    右击cmd,点击以管理员身份运行。

    在命令提示符下,键入以下命令并按 ENTER 在每个命令之后。

    获取/f ole32.dll

    regsvr32 ole32.dll

    运行以上两条命令后关闭命令提示符。

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

【讨论】:

以上是关于Windows 8 上的 Visual C++ 6.0的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Windows 7 机器上的 Microsoft Visual C++ 2010 中运行 OpenCV

无法从 Visual Studio 启动 gdb 以在 Windows 上的 Linux 子系统中远程调试 Linux C++ 项目

对于标准 C++,我应该将 Windows 8.1 SDK 或 Windows 10 SDK 与 Visual Studio 2017 一起使用吗?

是否有任何工具可以检测 Visual C++ 6.0 上的缓冲区溢出? [关闭]

Visual C++编程技巧之一

为啥cupy安装过程检测不到Microsoft Visual C++?