通过 Win32 检索 dll 版本信息 - VerQueryValue(...) 在 Win7 x64 下崩溃

2023-12-23

受人尊敬的开源 .NET 包装器实现(夏普比特 http://sharpbits.codeplex.com/) of Windows BITS 服务 http://en.wikipedia.org/wiki/Background_Intelligent_Transfer_Service无法识别 Win7 x64 下的底层 BITS 版本。

这是失败的源代码。 NativeMethods 是由 .NET 方法包装并通过 DllImport 属性修饰的本机 Win32 调用。

private static BitsVersion GetBitsVersion()
    {
        try
        {
            string fileName = Path.Combine(
                     System.Environment.SystemDirectory, "qmgr.dll");
            int handle = 0;
            int size = NativeMethods.GetFileVersionInfoSize(fileName, 
                                                            out handle);
            if (size == 0) return BitsVersion.Bits0_0;
            byte[] buffer = new byte[size];
            if (!NativeMethods.GetFileVersionInfo(fileName, 
                                                  handle, 
                                                  size, 
                                                  buffer))
            {
                return BitsVersion.Bits0_0;
            }
            IntPtr subBlock = IntPtr.Zero;
            uint len = 0;
            if (!NativeMethods.VerQueryValue(buffer,
                              @"\VarFileInfo\Translation", 
                              out subBlock, 
                              out len))
            {
                return BitsVersion.Bits0_0;
            }

            int block1 = Marshal.ReadInt16(subBlock);
            int block2 = Marshal.ReadInt16((IntPtr)((int)subBlock + 2 ));
            string spv = string.Format(
                 @"\StringFileInfo\{0:X4}{1:X4}\ProductVersion", 
                 block1, 
                 block2);

            string versionInfo;
            if (!NativeMethods.VerQueryValue(buffer, 
                                             spv, 
                                             out versionInfo, 
                                             out len))
            {
                return BitsVersion.Bits0_0;
            }
...

实施遵循MSDN说明 http://msdn.microsoft.com/en-us/library/ms647464(VS.85).aspx通过信。仍在第二次 VerQueryValue(...) 调用期间,应用程序崩溃并终止调试会话不加思索。 在崩溃之前再提供一些调试信息:

  • 特殊病毒 => “\StringFileInfo\040904B0\产品版本”
  • buffer => byte[1900] - 充满二进制数据
  • 块 1 => 1033
  • 区块2 => 1200

我通过Windows查看了目标“C:\Windows\System32\qmgr.dll”文件(BITS的实现)。它说产品版本是7.5.7600.16385。该值应该在 versionInfo 字符串中返回,而不是崩溃。有什么建议吗?


Nobugz 的答案确实指出了一个非常有效的问题(对此非常感谢!),但最终的杀手是 .NET 错误:在 x64 .NET 实现下,这种情况下的编组字符串失败。该错误在.NET4.0中已修复。这是报告的问题以及微软的答案。 http://connect.microsoft.com/VisualStudio/feedback/details/488941/p-invoke-memory-faults-when-marshaling-byref-ansibstr-on-x64

建议的解决方法是检索 IntPtr 而不是字符串作为输出并手动封送字符串。所以最终的代码(包括Nobugz的修复):

int block1 = Marshal.ReadInt16(subBlock);
int block2 = Marshal.ReadInt16(subBlock, 2);
string spv = string.Format(@"\StringFileInfo\{0:X4}{1:X4}\ProductVersion", 
                             block1, block2);

IntPtr versionInfoPtr;
if (!NativeMethods.VerQueryValue(buffer, spv, out versionInfoPtr, out len))
{
     return BitsVersion.Bits0_0;
}
string versionInfo = Marshal.PtrToStringAuto(versionInfoPtr);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 Win32 检索 dll 版本信息 - VerQueryValue(...) 在 Win7 x64 下崩溃 的相关文章

随机推荐

  • 如何使用 CultureInfo 格式化已弃用的货币?

    在 dotnet 中 以特定于文化的方式格式化货币的推荐方法是 据我所知 using System Globalization var info CultureInfo GetCultureInfo en GB return string
  • 节点组的位置在 SCNNode.runAction 开始时重置

    我有一些代码 当点击屏幕时 它会围绕 x 轴旋转多个 SCNNode 如下所示 func handleTap gestureRecognize UIGestureRecognizer let sceneView self view as S
  • 光栅图像似乎使用 R 的传单进行了移动

    我想使用 R 中的 leaflet 包绘制一些空间数据 但是生成的光栅图像与参考网格相比似乎发生了偏移 我怀疑地图投影问题 但我不是该主题的专家 因此任何帮助将不胜感激 这是绘制地图的最小代码 library leaflet library
  • 如何删除临时消息

    我正在尝试找出一种机制 将临时消息发布给用户 然后将其删除并替换为所有人都可见的消息 与 giphy 类似的行为 其中 Slash 命令显示交互式临时消息 并在用户决定发送哪个 gif 后创建频道消息 我也对更新临时消息感到好奇 我认为如果
  • Bootstrap 5 带有 html 内容的弹出窗口

    我试图将 bootstrap5 弹出窗口内容与 HTML 属性分开 就像对其他组件所做的那样 但我无法让它工作 var popoverTriggerList slice call document querySelectorAll data
  • Java 将 XML 文档渲染为 PDF

    我有一个 XML 文档 当前存储为内存字符串 并且希望将其呈现为 PDF 换句话说 PDF 内容将是 XML 文档 该方法呈现的 XML 是通用的 可能会发送多种类型的 XML 文档 我在弄清楚如何使用各种基于 Java 的框架来完成任务时
  • iPhone 5s 扬声器模式下的 iOS 7 机器人/乱码

    我们有一个 VOIP 应用程序 可以录制和播放音频 因此 我们使用 PlayAndRecord kAudioSessionCategory PlayAndRecord 音频会话类别 到目前为止 我们已成功地将其用于运行 iOS 6 和 iO
  • IE8 和 VS2008:如何禁用脚本调试?

    IE8 已经出来了 显然 每当您在调试模式下启动项目时 它都会自动打开脚本 JavaScript 调试 有谁知道如何关闭此功能 我搜索了 IE8 VS2008 设置 但没有看到任何内容 Edit 您不能只进入 Internet 选项并禁用调
  • 使用 System.Runtime.Caching,但是当我去检索它时,它是空的?

    我有一个 C WPF 应用程序 我正在尝试使用新的 System Runtime Caching 来实现缓存 当我向缓存中添加某些内容时 我会检查它并确认它确实存在 但是 当我重新启动应用程序时 它就从缓存中消失了 因此 在下面的示例中 输
  • 使用 ASIHTTPRequest 从 iOS 上传图像

    我的应用程序在注册时上传图像和用户 电子邮件 通行证 iOS 到 php 到 mySQL 电子邮件 用户 密码和图像名称都可以很好地保存到数据库中 它只是未上传到服务器上的文件夹的图像 所以这只是我的代码的一部分失败了 但是有人能看到哪里吗
  • HTTP 补丁 XmlHttpRequest 支持

    我正在开发一些待办事项应用程序 并希望使用 HTTP 方法 PATCH 来添加和删除待办事项 因为这在语义上比 PUT 更好 在后端我使用express js node js 在前端backbone js 使用jQuery进行ajax 我已
  • 当书签拖到工具栏时如何设置网站图标/图标?

    我为自己制作了一个小书签 它的功能很好 但当添加到 Opera 或 Firefox 的工具栏时 它只是呈现浏览器的默认书签图标 分别为地球仪和星星 我的网站有一个网站图标 窗口 选项卡甚至 网站 书签都使用我指定的网站图标 只是不是我的书签
  • 将 git repo 中的所有文件转换为 LF 行结尾的最简单方法是什么

    所以我有一个旧的仓库 有很多文件 有些是 CRLF 有些是 LF 我想要 1 将所有文件更改为 LF 我使用 dos2unix 来转换我的文件 但 git commit 忽略这些更改 我还将 git config global core a
  • 重新加载发布到 Github 页面的 Vue 网站时出现 404

    我已经部署了我的内容 distmaster 分支中的文件夹christopherkade github io 它已经部署了我的website https christopherkade com 成功了 但是当我使用导航栏导航时 christ
  • char **p,char *p[],char p[][] 之间的区别

    char p some string 创建一个指针 p 指向包含该字符串的块 char p some string 创建一个字符数组并在其中包含文字 第一个是常量声明 和二维数组一样吗 有什么区别 char p char p char p
  • 警告:函数“kill”的隐式声明

    我正在制作这些内容 include
  • 适用于 Windows 7 的 Korn-Shell?

    我们需要支持提供 Unix 和 Win32 端口的旧版应用程序 不幸的是 在游戏后期 很多粘合代码都是用 ksh 脚本编写的 仅适用于 unix 端口 而 Win32 端口已经失去了奇偶校验 我一直在尝试恢复它 并且一直在尝试一些 ksh
  • 解析的 KML 文件在我的应用程序中的 Google 地图中不显示路线

    我成功地从服务器和资产文件夹中解析了 KML 文件 并从 KML 文件中获取坐标 并能够从服务器端 KML 文件显示路线 但测试的问题是我已经从 Google 地图下载了两个位置之间路线的 KML 文件 并将 KML 文件放入资产文件夹中并
  • 如何启用 IntelliJ 2021.2 上的 Spring Boot Live Dev Tools 在修改后重建类并将更改部署到服务器?

    这是一个关于如何在 IntelliJ 2021 2 上启用 Dev Tools 项目并观察代码变化而无需重新启动 Tomcat 服务器的教程 为了使其发挥作用 您需要 1 在maven或gradle中启用devtools 在 Maven 中
  • 通过 Win32 检索 dll 版本信息 - VerQueryValue(...) 在 Win7 x64 下崩溃

    受人尊敬的开源 NET 包装器实现 夏普比特 http sharpbits codeplex com of Windows BITS 服务 http en wikipedia org wiki Background Intelligent