【问题标题】:Is there a setting in Visual Studio that affects the location a custom DLL function creates a file?Visual Studio 中是否存在影响自定义 DLL 函数创建文件的位置的设置?
【发布时间】:2021-07-28 06:59:26
【问题描述】:

我已经编写了自定义 DLL,其中包含适用于 pdf 的脚本语言的函数。当我调用我的创建函数时,它可以工作,但它会在我的 C++ 项目调试目录中创建 pdf。我没有指定一个完全合格的路径作为即时测试。是否有可以在视觉工作室中控制它并以某种方式在 dll 中的设置?如果我指定一个完整路径,它会返回一个错误,假设因为它是从我的项目文件夹中开始的......有人知道吗?

MV_EL_FunctionParameter pdfApCreate_parameters[] = {
    { "filename", 8, EPF_NORMAL },
    { "location", 8, EPF_NORMAL }
};
__declspec(dllexport) void bi_pdfApCreate(mvProgram prog, mvVariableHash parameters, mvVariable returnvalue, void **)
{
    int ret = LoadApWDll();
    if (!ret)
    {
        mvVariable_SetValue_Integer(returnvalue, 33333);
        return;
    }


    // INPUTS
    int filename_len;
    const char* filename;
    int location;

    // OUTPUT
    long id;

    // Not needed anymore, for a depricated Miva API function.
    //char* resolved_filename = NULL;
    //int resolved_filename_len;

    filename = mvVariable_Value(mvVariableHash_Index(parameters, 0), &filename_len);
    location = file_location(mvVariableHash_Index(parameters, 1));
    //mvFile_Resolve(prog, location, filename, filename_len, &resolved_filename, &resolved_filename_len);
    
    id = pApCreate((char*)filename);
    if (id) { mvProgram_Free(prog, const_cast<char*>(filename)); }
    mvVariable_SetValue_Integer(returnvalue, id);

}

这是人们离开的地方。这是为 Miva 脚本语言创建函数。这是他们用来构建它的自定义 API。 这是 Miva Mia 的图片。

【问题讨论】:

  • "它在我的 C++ 项目调试目录中创建 pdf。我没有指定完全限定的路径" - 这是你的错误。始终使用绝对路径,切勿使用相对路径。在任何给定时刻,您都不知道调用进程的“当前工作目录”指向何处。即使您在代码中调用了 `SetCurrentDirectory(),它也是一个竞争条件。 “Visual Studio 中是否有可以控制的设置” - 这不是您应该在项目设置中控制的内容。 “如果我指定了一个完整的路径,它会返回一个错误”——那么你做错了什么......
  • ... 如果需要,您可以在运行时从多个路径构建绝对路径。例如,如果您需要一个相对于 DLL 的绝对文件路径,您可以在运行时检索 DLL 的路径,截断其文件名,并根据需要附加新的文件夹/文件名。但是,由于您正在尝试创建新文件,因此您应该使用 Windows 为此目的预留的文件夹,例如在%APPDATA%MyDocuments 等系统文件夹下创建您自己的子文件夹,您可以获得路径通过使用SHGetFolderPath()SHGetKnownFolderPath() 询问Windows。
  • OK... 在我的脚本代码中,我不需要指定完全限定的路径,因为我的网络服务器应用程序指定一切就绪。我没有在上面发布的 C++ 代码中使用任何路径信息。该代码中没有路径信息。该代码创建了一个我用另一种语言调用的函数,我将其发送到创建 pdf 的路径。
  • "我将创建 pdf 的路径发送到哪里" - 您发送的具体路径是什么?相对路径还是绝对路径?如果是相对的,那么在将路径处理给 Windows 以实际创建文件之前,该函数是否足够聪明,可以将该路径转换为由网络服务器定义的绝对路径?如果路径是相对的,并且只是按原样提供给 Windows,那么您将受制于网络服务器的“当前工作目录”,它可能随时指向 任何地方。你真的没有提供有用的细节来帮助你。
  • 当它被调用时,该函数采用一个位置参数,该参数具体是脚本或数据。根据它是什么,Miva 创建由我在网络服务器中设置的任何路径指定的完整路径。

标签: c++ visual-studio dll


【解决方案1】:

Visual Studio 有一个指定 Working Directory 的设置,但仅在从 Visual Studio 运行时使用。

但是,您永远不应该依赖当前的工作目录。指定完整路径。

请显示“返回错误”的代码 - 这可能是你的错。

【讨论】:

  • 我确定是我的错!我不明白它会从哪里获得该目录信息。我运行一个 Miva mia Web 服务器,数据的位置和脚本都在该应用程序中设置。 DLL 位于 C:\Mivamia\Builtins\mrdll.dll...
  • @SquishyBrain 我看到你添加了代码。我对米瓦不熟悉。无论如何,当您调用pApCreate 时,filename 的值是多少?
  • 对不起,这是错误的。那只是文件名。位置就是路径。
  • @SquishyBrain Vlad 询问您filename实际值。它在运行时实际上是什么样子的?请举个例子。
  • 我不知道这不是一个 exe 它是一个 dll 构建我如何获得这些信息?
【解决方案2】:

看起来您正在写入 Win32(与 .Net 或 .Net Core 相比)。

我会推荐“硬编码路径” - 这太脆弱了。

相反,我会建议以下之一:

  • 从环境变量中读取路径
  • 使用相对于 .exe 的路径

在Win32中获取路径:

TCHAR szFileName[MAX_PATH];
GetModuleFileName(NULL, szFileName, MAX_PATH)

在 .Net 中获取路径:

System.IO.Path.GetDirectoryName(
    System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)

如果选择使用环境变量:

  • 可以在 Visual Studio 中设置变量
  • 对于“生产”,您可能会从 .bat 文件调用 .exe,并在 .bat 文件中设置环境变量

另一种选择是让 .exe 确定路径,并将路径字符串作为函数参数传递给 .dll :)

【讨论】:

  • 我不使用硬编码路径。路径作为参数发送到此函数。是的,它是 Win32。
  • 无法保证用户对该 .dll 文件的文件夹具有写入权限; Windows 中的文件夹很可能具有此类访问权限,例如 LOCALAPPDATA
  • “另一种选择是让 .exe 确定路径,并将路径字符串作为函数参数传递给 .dll :)”这正是我正在做的。虽然它不是从 .exe 调用的。它是从一个 Miva 脚本调用的,该脚本是一个已编译的 .mvc
  • 好的,你的 .dll 被脚本调用了。 .dll 正在读取从脚本传递给它的参数filenamelocation。问:请举例说明这两个值,当您在 MSVS 中以“测试模式”运行时?一个带有“完整路径”的示例(给出错误),另一个“有效”的示例(写入您的 MSVS 项目目录)?
  • 正是保罗。 Vlad 向我指出了一个能够调试它并将其附加到我的 Web 服务器可执行文件的方向。我发现了问题。函数 MvFile_Resolve 是 API 中不推荐使用的函数,它的工作是从 Web 服务器获取数据或脚本位置,将其与函数中发送的文件名/路径连接以创建完整路径。那没有发生。现在我需要找到一种方法来获取该信息,这应该得到修复。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多