在生成时或运行时获取解决方案路径

本文关键字:获取 解决方案 路径 运行时 | 更新日期: 2023-09-27 18:36:24

我有一个 C# 解决方案,我想在构建时将解决方案的路径设置为 app.config。 例如。假设我有c:'temp'visual studio'super fun project'super_fun_project.sln开放的解决方案。我生成并在其中一个测试项目中将应用设置更改为解决方案的完整路径。即

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="fullSolutionPath" value="{setAtBuild}"/>
  </appSettings>
</configuration>

如果我去c:'temp'visual studio'super fun project'Foobar.Tests'bin'Debug'Foobar.Tests.dll.config它看起来会

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="fullSolutionPath" value="c:'temp'visual studio'super fun project'super_fun_project.sln"/>
  </appSettings>
</configuration>

或者但是它需要格式化,以便在运行时我要求值时,我确实得到了正确的路径。我已经查看了转换,但我无法弄清楚如何设置解决方案路径。还有其他技巧可以得到这个吗?

在生成时或运行时获取解决方案路径

您可以做的是修改项目文件并添加 MsBuild 目标。

目标可以使用自定义内联任务,该任务的源代码集成到项目文件中。

因此,要添加此任务:

1)卸载项目(右键单击项目节点,选择"卸载项目")

2)编辑项目文件(右键点击项目节点,选择"编辑")

3)将

以下内容添加到项目文件中(例如到最后)并重新加载,现在当您构建时,配置文件将相应地修改。

<Project ...>
  ...
    <Target Name="AfterBuild">
      <RegexReplace FilePath="$(TargetDir)$(TargetFileName).config" Input="setAtBuild" Output="$(SolutionPath)" />
    </Target>
    <UsingTask TaskName="RegexReplace" TaskFactory="CodeTaskFactory" AssemblyName="Microsoft.Build.Tasks.Core" >
      <ParameterGroup>
        <FilePath Required="true" />
        <Input Required="true" />
        <Output Required="true" />
      </ParameterGroup>
      <Task>
        <Using Namespace="System.Text.RegularExpressions"/>
        <Code Type="Fragment" Language="cs"><![CDATA[
                File.WriteAllText(FilePath, Regex.Replace(File.ReadAllText(FilePath), Input, Output));
            ]]></Code>
      </Task>
    </UsingTask>
</Project>

在这里,我定义了输出以使用Visual Studio名为SolutionPath的MSBuild属性,但您可以重用此RegexReplace任务,并根据各种需求更新InputOutput参数。

我不知道

您的用例是什么,但您可以从项目的构建后事件调用自行开发的批处理文件来执行此操作。

示例:在项目中创建一个名为"updateconf.bat"的批处理脚本,确保它是 ANSII 编码的(可以使用 Notepad++ 编写脚本并确认 ANSII),否则在编译 VS 项目并检查输出时,您将收到一个异常,指示该文件以非法字符为前缀。

批处理脚本的内容:

@echo off > newfile & setLocal ENABLEDELAYEDEXPANSION
set old="{setAtBuild}"
set new=%2
set targetBinary=%3

cd %1
for /f "tokens=* delims= " %%a in (%targetBinary%.config) do (
set str=%%a
set str=!str:%old%=%new%!
>> newfile echo !str!
)
del /F /Q %targetBinary%.config
rename "newfile" "%targetBinary%.config"

然后在项目属性中添加一个调用批处理脚本的生成后事件:

call $(ProjectDir)'updateconf.bat "$(TargetDir)" "$(SolutionPath)" $(TargetFileName)