问题 在VS2008中全局(不是每用户)更改“调试/工作目录”


我在VS2008中有一个带有多个项目的C ++解决方案。此解决方案包含运行时所需的文件,这些文件根据路径加载 相对于解决方案目录 (例如。 "Testing/data/" + "dataN.bin")。

为了使这个解决方案起作用,我必须设置 工作目录设置 在项目中,它将指向解决方案目录(例如 Configuration Properties >> Debugging >> Working Directory = $(SolutionDir) )。当我在自己的电脑上调试时,这很好用。但是,当其他用户加载我的解决方案时,他的项目没有正确设置此属性。

我跟踪此设置不存储在项目文件中(PROJECT.vcproj),但在为其创建的用户特定文件中(PROJECT.vcproj.DOMAIN.USER.user)。

我想为所有用户存储此设置的方法,而不必一次又一次地手动设置。

我的想法是:

  • 找到一种方法 将其存储在.vcproj文件中 (不是用户特定的)或解决方案文件。
  • 找到一种方法来创建“默认用户特定文件“,从中开始所有用户特定的设置(并且可以稍后修改)。

但是,我没有找到办法做其中任何一个。

一些注释/限制:

  • 我需要使用许多大文件作为这些资源,因此我想避免对不同的目录执行复制。
  • 解决方案需要支持多种构建配置(调试,发布等)。
  • 如果可能的话,我想避免使用前/后构建脚本,以保持简单(低优先级)。

任何帮助将不胜感激...提前感谢。


9067
2018-06-20 11:56


起源



答案:


没有这样的财产。有更大的问题,在部署解决方案后,这也需要工作。然后工作目录不会是“解决方案”目录,目标机器上没有。

假设工作目录与EXE目录相同,您的工作要好得多。这将是调试时和目标机器上的默认值。您可以使用链接器设置完全控制EXE文件的位置。通过获取代码中的EXE目录,您可以通过另一个工作目录保护自己免受运行程序的快捷方式的影响,这样您就可以生成绝对路径。使用GetModuleFileName(),传递NULL以获取EXE文件的路径。

另一个标准解决方案是将EXE所需的任何类型的资源复制到与构建输出文件夹相关的文件夹中。您使用Pre-Build事件执行此操作,使命令行看起来类似于:

if not exist "$(OutDir)\Testing" md "$(OutDir)\Testing"
xcopy /d /s "$(SolutionDir)\Testing\*.*" "$(OutDir)\Testing

请注意/ d选项如何确保仅在Testing文件夹内容发生更改时才进行复制。


4
2018-06-20 12:46



复制资源:这可以解决问题,但是我有大量资源要复制(在这种情况下,是大型测试向量),每次复制这些资源都浪费时间和内存。另外,我有多个构建配置(发布,调试,...),这将导致我希望避免的进一步复制。有意义的是,这些向量位于根“解决方案”目录中,因为此数据由多个项目(以不同方式)使用。另外,我想在解决方案的文件列表中维护顺序(关于目录结构)。 - scooz
另一方面,将可执行结果复制到根解决方案目录不仅会导致根目录混乱,而且还不能正确支持多个构建配置(将保留覆盖相同名称的文件等)。似乎出于调试目的,最合乎逻辑的做法是更改工作目录。关于你提出的部署问题(我同意这一点),我宁愿使那里的事情比调试时复杂化(因为我部署的次数少于调试次数) - scooz
这就是为什么我指出了xcopy / d选项的行为。您只需支付一次副本费用。 - Hans Passant
没错,但它仍然需要我复制周围的东西。我们在这里谈论千兆字节的数据...... :) - scooz
将数据放入与可执行文件的每个配置目录位于同一级别的目录中。然后使用相对于您的可执行文件的.. \ data之类的路径引用您的数据。 - oefe


答案:


没有这样的财产。有更大的问题,在部署解决方案后,这也需要工作。然后工作目录不会是“解决方案”目录,目标机器上没有。

假设工作目录与EXE目录相同,您的工作要好得多。这将是调试时和目标机器上的默认值。您可以使用链接器设置完全控制EXE文件的位置。通过获取代码中的EXE目录,您可以通过另一个工作目录保护自己免受运行程序的快捷方式的影响,这样您就可以生成绝对路径。使用GetModuleFileName(),传递NULL以获取EXE文件的路径。

另一个标准解决方案是将EXE所需的任何类型的资源复制到与构建输出文件夹相关的文件夹中。您使用Pre-Build事件执行此操作,使命令行看起来类似于:

if not exist "$(OutDir)\Testing" md "$(OutDir)\Testing"
xcopy /d /s "$(SolutionDir)\Testing\*.*" "$(OutDir)\Testing

请注意/ d选项如何确保仅在Testing文件夹内容发生更改时才进行复制。


4
2018-06-20 12:46



复制资源:这可以解决问题,但是我有大量资源要复制(在这种情况下,是大型测试向量),每次复制这些资源都浪费时间和内存。另外,我有多个构建配置(发布,调试,...),这将导致我希望避免的进一步复制。有意义的是,这些向量位于根“解决方案”目录中,因为此数据由多个项目(以不同方式)使用。另外,我想在解决方案的文件列表中维护顺序(关于目录结构)。 - scooz
另一方面,将可执行结果复制到根解决方案目录不仅会导致根目录混乱,而且还不能正确支持多个构建配置(将保留覆盖相同名称的文件等)。似乎出于调试目的,最合乎逻辑的做法是更改工作目录。关于你提出的部署问题(我同意这一点),我宁愿使那里的事情比调试时复杂化(因为我部署的次数少于调试次数) - scooz
这就是为什么我指出了xcopy / d选项的行为。您只需支付一次副本费用。 - Hans Passant
没错,但它仍然需要我复制周围的东西。我们在这里谈论千兆字节的数据...... :) - scooz
将数据放入与可执行文件的每个配置目录位于同一级别的目录中。然后使用相对于您的可执行文件的.. \ data之类的路径引用您的数据。 - oefe


  1. 配置 像往常一样调试设置(设置工作目录,设置参数等...)但只使用相对路径,变量。不要使用像D:\ MyProject \ libs这样的绝对路径
  2. 然后保存您的解决方案 关闭Visual Studio
  3. 转到项目目录并查找 PROJECT.vcproj.COMPUTERNAME.USER.user
  4. 改名 它来 PROJECT.vcproj.user (此文件将是通用调试配置,您可以将其提交给源代码控制)
  5. 打开Visual Studio,如果需要,可以额外添加调试设置。 (额外信息将存储在特定于您的PROJECT.vcproj.COMPUTERNAME.USER.user文件中。 PROJECT.vcproj.COMPUTERNAME.USER.user将覆盖 继承配置)

PROJECT.vcproj.user文件示例如下

<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
    ProjectType="Visual C++"
    Version="9,00"
    ShowAllFiles="false"
    >
    <Configurations>
        <Configuration
            Name="Release|Win32"
            >
            <DebugSettings
                Command="$(ProjectDir)..\Deploy\$(ConfigurationName)\$(TargetFileName)"
                WorkingDirectory="$(ProjectDir)..\Deploy\$(ConfigurationName)\"
                CommandArguments=""
                Attach="false"
                DebuggerType="3"
                Remote="1"
                RemoteMachine="LOCALHOST"
                RemoteCommand=""
                HttpUrl=""
                PDBPath=""
                SQLDebugging=""
                Environment=""
                EnvironmentMerge="true"
                DebuggerFlavor="0"
                MPIRunCommand=""
                MPIRunArguments=""
                MPIRunWorkingDirectory=""
                ApplicationCommand=""
                ApplicationArguments=""
                ShimCommand=""
                MPIAcceptMode=""
                MPIAcceptFilter=""
            />
        </Configuration>
        <Configuration
            Name="Debug|Win32"
            >
            <DebugSettings
                Command="$(ProjectDir)..\Deploy\$(ConfigurationName)\$(TargetFileName)"
                WorkingDirectory="$(ProjectDir)..\Deploy\$(ConfigurationName)\"
                CommandArguments=""
                Attach="false"
                DebuggerType="3"
                Remote="1"
                RemoteMachine="LOCALHOST"
                RemoteCommand=""
                HttpUrl=""
                PDBPath=""
                SQLDebugging=""
                Environment=""
                EnvironmentMerge="true"
                DebuggerFlavor="0"
                MPIRunCommand=""
                MPIRunArguments=""
                MPIRunWorkingDirectory=""
                ApplicationCommand=""
                ApplicationArguments=""
                ShimCommand=""
                MPIAcceptMode=""
                MPIAcceptFilter=""
            />
        </Configuration>
    </Configurations>
</VisualStudioUserFile>

10
2018-03-15 15:27



您似乎可以删除除WorkingDirectory之外的所有属性,如果这是您要为其设置默认值的唯一属性 - Joe


您可以考虑使用“配置属性/常规/输出目录”或“配置属性/链接器/输出文件”,而不是“调试器/工作目录”设置。这些设置是按项目而不是按用户进行的,如果您保持工作目录不变 这个 是app工作目录的默认值。


1
2018-06-20 12:28



如果事情没有按照我的方式进行,我可能不得不这样做,尽管我会避免这种情况(请参阅我在Hans Passant的回答中的评论)。在以前版本的Visual Studio(例如2005)中,这种行为不同吗? - scooz


我想知道这是否可能,因为用户可能没有足够的权限来访问和读/写目录,我想VS检查用户是否有权访问目录,这可能是为什么只有一个帐户基于选项。


0
2018-06-20 12:28