【问题标题】:How to programatically set or clear the 32BIT flag?如何以编程方式设置或清除 32 位标志?
【发布时间】:2009-06-01 22:55:11
【问题描述】:

编译时,我总是将它设置为 Any CPU。但是,有些客户没有所需二进制文件的 64 位版本,即使在 x64 系统上运行也是如此。在这些情况下,我要求他们使用 corflags.exe /32BIT+ 选项修改我的二进制文件:

http://msdn.microsoft.com/en-us/library/ms164699(VS.80).aspx

如果 64 位版本不存在,我想使其透明并在安装期间自己修改二进制文件。我宁愿不要自己调用 corflags.exe,因为这意味着我需要重新分发我们的运输要求中不允许的应用程序。

所以我的问题是;有没有办法自己以编程方式修改这个标志,或者直接修改二进制文件(它只是在文件本身的某处设置一个字节)?

【问题讨论】:

  • 不确定您这样做是为了达到什么目的?
  • 另一种解决方案可能是包含您正在使用的库的 64 位版本,如果用户拥有 32 位版本并且在 64 位机器上运行,则本地版本将在搜索中您的应用程序的路径,应该加载。
  • @Mitch:我们引用了第三方库,而不是开源的。它是一个 C++ 混合模式库。在早期版本中,只有 32 位版本可用。所以即使他们在 x64 机器上运行,他们也没有这个库的 x64 版本。我的工具是 C# 并编译为 Any CPU。因此,当它在其中一台机器上运行时,它找不到正确的 DLL。
  • @Average Joe:它是第 3 方库,不是开源的,我们不允许重新分发第 3 方工具(法律原因),这就是为什么我也不能只发送 corflags

标签: c# .net runtime corflags


【解决方案1】:

我还没有尝试过,但是您能否在二进制文件的副本上运行 corflags 并执行二进制 diff 以确定修改了哪些偏移量。您可以将此作为安装脚本的构建操作,并将偏移量存储在安装程序中。

在安装时只需根据需要更改偏移量。

我当然不会赞同这样的行为,只是说说而已

;-)

顺便说一句,如果您不断需要将程序集标记为 32 位,您可以考虑只针对该平台而不是事后将其更改为 32 位。

干杯。

【讨论】:

    【解决方案2】:

    为什么不专门为两种架构(32 位和 64 位)构建程序集,将两者都包含在您的安装程序中,然后在安装时检测您的客户端拥有的此依赖程序集的哪个版本,然后安装适当的应用程序的架构版本。这样一来,手动修改二进制文件或需要在安装程序中包含 corflags 就不会麻烦了。

    【讨论】:

    • 我现在倾向于这种方法,我只是希望避免分发 2 个二进制文件。
    • 我正在构建 X86 和 AnyCPU,但它使安装程序的大小增加了一倍。我们构建了一个简单的安装程序来确定要安装的版本(基于 Office 安装类型 32/64)。如果能够告诉安装程序从 AnyCPU 安装哪个版本而不是捆绑两者,并通过安装仅 x86 的 MSI 来强制在 X64 上安装 X86,那就太好了。
    【解决方案3】:

    对于文件本身,我相信(尚未确认)您可以自己修改 IMAGE_COR20_HEADER。只需设置 MinorRuntimeVersion 就可以了。这是关于如何使用 IMAGE_COR20_HEADER 来确定加载哪个运行时的(有些过时的)解释:http://blogs.msdn.com/joshwil/archive/2004/10/15/243019.aspx

    为什么不总是为 x86 编译,64 位运行时会给您带来什么好处?

    请注意,某些代码(interop/P/invoke)只能在 32 位或 64 位运行时中运行,因此仅将相同的程序集加载到另一个运行时中是行不通的。

    编辑:快速而肮脏的样本来读取 IMAGE_COR20_HEADER:

    _pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(_pFileBase);
    _pNTHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(_pFileBase + _pDosHeader->e_lfanew);
    _pFileHeader = reinterpret_cast<PIMAGE_FILE_HEADER>(&_pNTHeader->FileHeader);
    _pOptionalHeader = reinterpret_cast<PIMAGE_OPTIONAL_HEADER>(&_pNTHeader->OptionalHeader);
    IMAGE_DATA_DIRECTORY const* entry = NULL;
    entry = &pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER];
    if (entry->VirtualAddress == 0 || entry->Size == 0  || entry->Size < sizeof(IMAGE_COR20_HEADER)) {
    return E_FAIL;
    }
    pClrHeader = reinterpret_cast<IMAGE_COR20_HEADER*>(RtlImageRvaToVa32(_pNTHeader, _pFileBase, entry->VirtualAddress, 0));
    

    不相信这是一个好主意,但将其作为安装程序步骤。

    【讨论】:

      【解决方案4】:

      如果您可以在安装过程中检测到这一点,为什么不直接从安装程序中运行 corflags.exe?这对我来说听起来好多了,而不是尝试自己更改二进制数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-25
        • 1970-01-01
        • 2018-10-28
        • 1970-01-01
        • 1970-01-01
        • 2010-11-06
        • 1970-01-01
        相关资源
        最近更新 更多