为什么只有当可执行文件在 Visual Studio 下运行时 CreateFileA 才会失败?

2024-03-25

我写了一个简单的check_file_ref函数使用 WinAPI 检查两个路径是否引用同一个文件。代码没问题。它是用 C 语言的 Visual Studio 2017 编译的(标志/TC).

奇怪的是CreateFileA当可执行文件在 Visual Studio 下运行(即执行而不调试)时,(winapi) 总是失败,返回无效的文件句柄。否则,当可执行文件在 Visual Studio 外部运行时,它会按预期工作。

任何情况下工作目录都是相同的。

main.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

/**
 * Check whether two paths reference the same file.
 * @param p1 File path 1.
 * @param p2 File path 2.
 * @return 0 same file, 1 different files, < 0 on failure.
 */
int
check_file_ref(char const * p1, char const * p2)
{
    if ( !p1 || !p2 )
        return -1;
    if ( p1 == p2 )
        return 0;
    if ( strcmp(p1, p2) == 0 )
        return 0;

    int ret;
    DWORD share, flags;
    HANDLE f1, f2;
    BY_HANDLE_FILE_INFORMATION s1, s2;

    ret = -1;
    share = FILE_SHARE_READ | FILE_SHARE_WRITE;
    flags = FILE_ATTRIBUTE_NORMAL;

    f1 = CreateFileA(p1, GENERIC_READ, share, NULL, OPEN_EXISTING, flags, NULL);
    f2 = CreateFileA(p2, GENERIC_READ, share, NULL, OPEN_EXISTING, flags, NULL);

    if ( f1 == INVALID_HANDLE_VALUE ) {
        fprintf(stderr, "Could not open %s file, error %d\n", p1, GetLastError());
        goto cleanup;
    }
    if ( f2 == INVALID_HANDLE_VALUE ) {
        fprintf(stderr, "Could not open %s file, error %d\n", p2, GetLastError());
        goto cleanup;
    }
    if ( GetFileInformationByHandle(f1, &s1) == 0 ) {
        fprintf(stderr, "Could not get %s file information, error %d\n", p1, GetLastError());
        goto cleanup;
    }
    if ( GetFileInformationByHandle(f2, &s2) == 0 ) {
        fprintf(stderr, "Could not get %s file information, error %d\n", p2, GetLastError());
        goto cleanup;
    }

/*
    The identifier (low and high parts) and the volume serial number uniquely
    identify a file on a single computer. To determine whether two open handles
    represent the same file, combine the identifier and the volume serial number
    for each file and compare them.

    See
    https://learn.microsoft.com/fr-fr/windows/desktop/api/fileapi/nf-fileapi-getfileinformationbyhandle
    https://learn.microsoft.com/fr-fr/windows/desktop/api/fileapi/ns-fileapi-_by_handle_file_information
*/
    ret = !(s1.dwVolumeSerialNumber == s2.dwVolumeSerialNumber
        &&  s1.nFileIndexLow == s2.nFileIndexLow
        && s1.nFileIndexHigh == s2.nFileIndexHigh);

cleanup:
    CloseHandle(f2);
    CloseHandle(f1);
    return ret;
}


int main()
{
    int ret;
    char workingDir[256];

    /* Both paths reference the same file.
       One is relative, the other absolute. */
    char * p1 = "hello.txt";
    char * p2 = "C:/Users/bro/source/repos/tests/x64/Debug/hello.txt";

    ret = GetModuleFileNameA(NULL, workingDir, sizeof(workingDir));
    printf("working dir: %s\n", (ret == 0 ? "err" : workingDir));

    /* Should return 0. */
    ret = check_file_ref(p1, p2);
    printf("p1: %s\n", p1);
    printf("p2: %s\n", p2);
    printf("check_file_ret ret %d ", ret);

    if      ( ret == 0 ) printf("(same file)\n");
    else if ( ret == 1 ) printf("(different files)\n");
    else                 printf("(error)\n");

    return 0;
}

可视化下运行可执行文件:

创建文件A失败 https://i.stack.imgur.com/uCk1A.png

可执行文件直接从命令行运行:

CreateFileA 有效 https://i.stack.imgur.com/9q3cg.png

Why is CreateFileA仅当可执行文件在 Visual Studio 下运行时才失败?


当您从 VisualStudio 运行应用程序时,默认工作目录是项目位置,由 VS 宏定义$(ProjectDir)。您可以通过打开项目属性来更改它:右键单击中的项目解决方案浏览器并选择特性从上下文菜单中。那里选择调试并改变工作主任y 财产。例如,在您的情况下,解决方案可能是$(OutDir)或所需位置的绝对路径。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么只有当可执行文件在 Visual Studio 下运行时 CreateFileA 才会失败? 的相关文章

  • GetType() 在 Type 实例上返回什么?

    我在一些调试过程中遇到了这段代码 private bool HasBaseType Type type out Type baseType Type originalType type GetType baseType GetBaseTyp
  • ComboBox DataBinding 导致 ArgumentException

    我的几个类对象 class Person public string Name get set public string Sex get set public int Age get set public override string
  • 为什么在 WebApi 上下文中在 using 块中使用 HttpClient 是错误的?

    那么 问题是为什么在 using 块中使用 HttpClient 是错误的 但在 WebApi 上下文中呢 我一直在读这篇文章不要阻止异步代码 https blog stephencleary com 2012 07 dont block
  • C# 数据表更新多行

    我如何使用数据表进行多次更新 我找到了这个更新 1 行 http support microsoft com kb 307587 my code public void ExportCSV string SQLSyntax string L
  • 从客户端访问 DomainService 中的自定义对象

    我正在使用域服务从 Silverlight 客户端的数据库中获取数据 在DomainService1 cs中 我添加了以下内容 EnableClientAccess public class Product public int produ
  • 使用 GCP 的数据存储区时如何区分代码是在模拟器中运行还是在 GKE 中运行

    按照中给出的说明进行操作后 我不确定是否遗漏了任何内容https cloud google com datastore docs tools datastore emulator https cloud google com datasto
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • 识别 Visual Studio 中的重载运算符 (c++)

    有没有办法使用 Visual Studio 快速直观地识别 C 中的重载运算符 在我看来 C 中的一大问题是不知道您正在使用的运算符是否已重载 Visual Studio 或某些第三方工具中是否有某些功能可以自动突出显示重载运算符或对重载运
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 如何在 C 中安全地声明 16 位字符串文字?

    我知道已经有一个标准方法 前缀为L wchar t test literal L Test 问题是wchar t不保证是16位 但是对于我的项目 我需要16位wchar t 我还想避免通过的要求 fshort wchar 那么 C 不是 C
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 保护 APK 中的字符串

    我正在使用 Xamarin 的 Mono for Android 开发一个 Android 应用程序 我目前正在努力使用 Google Play API 添加应用内购买功能 为此 我需要从我的应用程序内向 Google 发送公共许可证密钥
  • C++ 中的双精度型数字

    尽管内部表示有 17 位 但 IEE754 64 位 浮点应该正确表示 15 位有效数字 有没有办法强制第 16 位和第 17 位为零 Ref http msdn microsoft com en us library system dou
  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • 这个可变参数模板示例有什么问题?

    基类是 include
  • Readfile 从大文件中读取 0 字节?

    我正在尝试通过以下方式发送一个大文件readfile 但是 没有任何内容发送到浏览器 并且readfile 回报0 not false 我尝试发送的文件大小为 4GiB 并且可由 PHP 读取 我正在设置set time limit 0 以
  • GCC 的“-Wl,option”和“-Xlinker option”语法之间有区别吗?

    我一直在查看一些配置文件 并且看到它们都被使用 尽管在不同的体系结构上 如果您在 Linux 机器上使用 GCC 将选项传递给链接器的两种语法之间有区别吗 据我所知 阅读 GCC 手册时 他们的解释几乎相同 From man gcc Xli
  • 灵气序列解析问题

    我在使用 Spirit Qi 2 4 编写解析器时遇到一些问题 我有一系列键值对以以下格式解析
  • OpenCV SIFT 描述符关键点半径

    我正在深入研究OpenCV的SIFT描述符提取的实现 https github com Itseez opencv blob master modules nonfree src sift cpp 我发现了一些令人费解的代码来获取兴趣点邻域

随机推荐

  • Liquibase:如何禁用 FILENAME 列检查?

    对于我们的应用程序 我们使用 liquibase 我们需要从命令行 在生产中手动 运行数据库迁移 并在应用程序启动时自动运行数据库迁移 测试环境等 问题是 Liquibase 将整个文件名视为变更集身份的一部分 因此如果路径不同 它会尝试重
  • Java重载和继承规则

    我一直在学习 因为我有考试 而且我对 Java 的大部分内容都没有太多问题 但我偶然发现了一条我无法解释的规则 这是一个代码片段 public class A public int method Object o return 1 publ
  • 两个 Div 彼此相邻,然后堆叠响应式更改

    我正在努力实现一些我确信应该比我现在做的更容易的事情 我正在使用 Skeleton 响应式框架 到目前为止一切都很好 这是我想要实现的目标的图表 这将被放置在一列中 一旦该列的大小减小 我希望它按照图中的第二个示例堆叠 div 我尝试了几种
  • 从 tfs 构建中排除测试

    我想从持续集成构建中排除一些测试 但我还没有找到这样做的方法 我尝试过的事情之一是将这些测试的优先级设置为 2 然后在构建中我指定最低测试优先级 1 但它仍然运行这些测试 任何帮助将不胜感激 您应该使用 测试类别 方法 而不是使用已描述的
  • 如何永久清除在启用软删除的情况下创建的整个 azure keyvault?

    当您创建启用了软删除的 azure keyvault 时 即使您将其删除并从头开始重新创建 该 keyvault 仍会保留 启用软删除后 标记为已删除资源的资源将保留指定时间段 默认为 90 天 该服务还提供了一种恢复已删除对象的机制 本质
  • 如何将水平滚动视图移动到特定位置?

    我使用的scrollView没有任何listView或gridview 我刚刚向其中添加了相同的视图 但知道我想以编程方式滚动到特定位置 这可能吗 请帮助我使用水平滚动 你可以使用这个方法 horizontalScrollView scro
  • Angular Jasmine FormControl 单元测试 valueChanges

    我想对以下方法进行单元测试 this boxValue subscribeToFilterChanges void this filterBox valueChanges subscribe data gt if data this box
  • 加入 PIG 对阵 COGROUP

    当我在 pig 中使用 COGROUP 而不是 JOIN 时 有什么优势 性能 没有地图减少 吗 http developer yahoo com hadoop tutorial module6 html http developer ya
  • Kotlin 网站上的“返回 Unit 的方法的构建器风格用法”让我感到困惑

    The IdiomsKotlin 官方文档的部分包含这个例子 http kotlinlang org docs reference idioms html builder style usage of methods that return
  • Kotlin 中带有新参数的 Paging 3.0 列表

    我有以下代码 val history Flow
  • 轻微破坏的意义

    在 C 17 中 新的std optional要求它可以轻易被破坏 如果T在 Optional object dtor 中是可以轻易破坏的 optional 1 Effects If is trivially destructible v
  • sizeof(x) 和 sizeof(p_x) 之间有什么区别

    你能告诉我两者有什么区别吗sizeof x and sizeof p x 在下面的代码中 int x 10 p x p x int malloc 10 sizeof int sizeof x 给出数组使用的字节数x sizeof p x 给
  • 程序退出时如何删除文件? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 有没有办法注册一个文件 以便在Python退出时将其删除 无论它如何退出 我正在使用长期存在的临时文件 并希望确保它们被清理 该文件必
  • 启动屏幕故事板迁移问题

    我有一个用 Objective C 构建的应用程序 它使用启动屏幕图像集作为启动画面 根据最近苹果公司的新指南 适用于 iPhone 或 iPad 的应用程序必须使用 iOS 13 SDK 或更高版本构建 并且 使用 Xcode 故事板提供
  • 如何检查同一个java程序的两个实例是否正在运行?

    您好 我正在制作一个将通过 javaw exe 运行的程序 因此它不直接可见 现在我的问题是有时 意外地 用户可能会运行同一应用程序的多个实例 例如输入javaw myProgram两次 在这种情况下 如果程序已经在运行 有什么方法可以阻止
  • Bootstrap Popover 一键点击即可工作 - JavaScript

    我有一些引导按钮 单击按钮时应该显示一个弹出窗口 usernameL onclick function e e currentTarget id popover html true 当网站加载并且我第一次单击按钮时 没有任何反应 如果我第二
  • AlamoFire 在后台会话中下载

    我在新应用程序中使用 Alamofire 基于 Alamofire 的下载管理器示例 我需要一些有关使用后台会话下载文件的说明 我需要重写 SessionDelegate 才能使其正常工作吗 要不就backgroundCompletionH
  • NoClassDefFoundError:android.support.v7.widget.helper.ItemTouchHelper$3

    嗨 我想创建滑动删除RecyclerView结果是崩溃 看着那 这build gradle 我导入了所需的所有库 在代码中我可以使用ItemTouchHelper类但是当我想刷一个项目时它崩溃了 build gradle compile c
  • 在 groupby 之后将组与一个数据帧合并

    我试图回答这个问题 https stackoverflow com questions 47117982 insert missing category for each group in pandas dataframe通过组级合并 下面
  • 为什么只有当可执行文件在 Visual Studio 下运行时 CreateFileA 才会失败?

    我写了一个简单的check file ref函数使用 WinAPI 检查两个路径是否引用同一个文件 代码没问题 它是用 C 语言的 Visual Studio 2017 编译的 标志 TC 奇怪的是CreateFileA当可执行文件在 Vi