双模式执行可能吗?

有点历史…我有3个系统,我花了时间,DOS 6.22系统,Windows 95系统,和现代Windows 7(64位)系统。 当我升级到Win7-64时,一些我最喜欢的命令行工具停止工作,所以我决定自己重新编写它们。 我唯一的2个编译器是Borland Turbo C ++ 3.0和Visual Studio 2008,他们在构build2个版本,DOS 16位和Windows 7 32位(也可能构build了64位,我猜也可以。 )我的Win95系统出现了问题。 DOS版本在那里工作的很好,但是因为我花时间在Win7版本中支持LFN,所以我想用我的Win95系统。 所以经过大量的研究,我发现并购买了Visual Studio 6(根据我所研究的最后一个支持Win95的代码)复制了代码(当然不得不重写代码),编译得很好, 🙂

下一次我不得不在DOS模式下启动我的Win95系统时发生了问题。 程序停止工作(当然),因为Win95没有加载。 我真的不想要安装2个程序副本(需要2个不同的文件名),所以我希望有一种方法将2个版本连接成一个文件。 如果我在DOS下执行它,而不是说它需要Windows,它将跳转到程序的DOS部分。 这样,它将是一个单一的程序,如果加载Win95,则支持LFN,如果Win95未加载,则不支持。 由于Win95版本在Win7-64中也可以正常工作,所以它可能会生成一个适用于所有3个系统的单一版本(这将是额外的好处)。

我做了一些networkingsearch,找不到任何与我正在寻找的东西密切相关的东西。 所以我不知道这是否可能。 我可能还需要另外一个编译器,但是考虑到它会有多大,我可能负担得起。 我的网页search确实导致了信息,使我相信它“应该”成为可能。 它只需要一个不同于一个Windows编译器的exe头文件。它可能需要我重新编写32位的DOS版本并使用DOS扩展器(对于保护模式,假设我找不到方法包括它在文件本身。)这是可以接受的(虽然不是理想的)。我宁愿在DOS部分有16位代码,在Windows部分有32位代码(为了最大的兼容性)。

有没有人有这样的信息? 如果你能指出我正确的方向,将不胜感激。

Visual Studio 6的文档在这里描述了/STUB选项,只需在DOS程序的DOS版本中指出。

我没有VS6的方便,所以我不能太具体,但在项目设置GUI中,应该有一个“附加选项”设置链接器部分。

我不知道在Windows 7可执行文件中是否继续执行,但是在Win95中,可执行文件(EXE)实际上有两个入口点 – 一个是DOS可以找到的“正常”的,另一个是Windows可以使用的。 DOS入口点通常是一个非常简单的默认设置,只会打印“这是一个Windows程序”并退出。 你实际上可以重写这个默认值,并让链接器使用你自己的代码,但是它是非常有限的。

我建议做的是添加逻辑到您的DOS 6.22版本(如“sed”),将检查操作系统级别,如果它符合正确的标准,将参数传递给第二个可执行文件(例如“sedx”)来自“更新”的操作系统的功能。

那么答案就是您用于Windows代码的链接器中的/ stub选项。 任何人后来发现问题的一些额外的信息….我不得不做了几天的网络搜索,发现似乎没有对我的特定问题的另一个答案。

存根要求DOS模式可执行文件至少有40个字节的标题。 在与多个“DO”给你一个合适大小的头文件(Borland Turbo C ++不会)之后,不能转换我的代码之后,我不得不变得偷偷摸摸/幻想。 顺便说一句 – Visual C 1.52C(最后一个支持DOS的Visual C)将打开正确的标题,将打开WatCom。

如果你是面对同样的问题,我是 – 你使用的编译器将不会正确大小的头,你的代码是太特定编译器来轻松转换,你可以做我最后做的事情。 我使用Open WatCom编写了一个小的(“Hello World”)Windows程序,使用我的exe文件(简称Borland创建的)头文件作为存根。 打开WatCom将自动调整标题。 然后,我使用十六进制编辑器来读取标题信息以获取存根的结束地址,并使用部分文件复制器将该程序的该部分复制到名为“stub.exe”的文件(剥离Windows代码)。使用相同的十六进制编辑器,我清除了标头中的PE指针。 我现在有一个工作的DOS exe文件,也可以作为一个存根。 拿我的存根到我的Windows编译器,并链接它。它很好,所有功能充分实现:)

仅供参考 – 剥离Windows部分所需的信息并清零PE指针。

第一个字节是偏移0(当然,但有些人可能没有意识到,并认为它是字节1.)还要记住,大多数十六进制编辑器(通过他们的名字)给你的十六进制格式的数字。

偏移量2和3,文件DOS部分的最后一个字节的字节数,低字节 – 高字节格式。 也就是说,偏移2是低的,3是高的。 所以把它们反过来,你会得到一个从0到511的数字(十六进制的0 – 1ff)。0表示整个512字节(十六进制数为200)的字节被使用。

偏移量4和5(同样是低/高格式)是DOS部分中512(200(十六进制))字节块的数量。 切记反转数字,最后一个块可能只是一个部分块。 所以,减去一个,乘以512(200十六进制),添加从2-3的数字,你有多少个字节在DOS部分。 因为你从0开始,减1,你现在知道只复制字节0 – “无论总数”到您的存根exe文件。

偏移量60-61(十六进制3C-3D)是指向PE(或可移植可执行文件)部分代码(Windows跳转到的部分)的开始的指针。它应该刚刚过去(我的软件被填充了一些零),代码的DOS部分结束。 这一点在这个时候并不重要,因为我们只是把它们变成0(PE部分已经被剥离了)。你可以使用这个来确认你已经选择了正确的“DOS结束”偏移量。

我使用的工具是:打开WatCom在http://www.openwatcom.org/index.php/Main_Page和部分复制在http://www.virtualobjectives.com.au/utilitiesprogs/partcopy.htm

我不知道在哪里可以找到我使用的十六进制编辑器。 我使用了CEdit,一个我真正喜欢的DOS程序,但一直没能在网上找到。 不得不使用DOSBox,因为Win7将不能运行它。 也许还有其他编译器可以做同样的事情,可能还有大量的部分文件复制器。 这些是我使用的工具。