我最终能够让 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 构建了一个可行的宏处理器,我可以对这个应用程序进行转换。