2

I'm trying to write a post-build event for a C# project. And I'm using a custom console app (myTool.exe) to do that.

For example, the post-build event is

"$(SolutionDir)tools\myTool.exe" "$(SolutionDir)myProject\bin\" Debug

(All paths is quoted because they could contain whitespaces.)

Before escaping, $(SolutionDir) is D:\Some\MySystem\. After escaping, it should become D:\\Some\\MySystem\\.

How to escape all the \ in $(SolutionDir) in this way in a csproj file?

I have tried to use this approach, but it seems not working for $(SolutionDir):

<PropertyGroup>
  <EscapedSolutionDir>$(SolutionDir.Replace('\\', '\\\\'))</EscapedSolutionDir>
  <EscapedTargetDir>$(TargetDir.Replace('\\', '\\\\'))</EscapedTargetDir>
</PropertyGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
  <Exec Command="&quot;$(EscapedSolutionDir)source\\Native\\Output\\NativeLibraryCopier.exe&quot; &quot;$(EscapedSolutionDir)&quot; &quot;$(ConfigurationName)&quot; &quot;$(PlatformName)&quot; &quot;$(TargetDir)&quot;" />
</Target>

PS: See this for why I have to replace the backslash.

zwcloud
  • 4,546
  • 3
  • 40
  • 69
  • Why does it need to be escape, am i missing something? – TheGeneral Jan 30 '18 at 05:47
  • You should Replace '\' with "\\"? As per my understanding escape is not the correct word here. Also please post code, you tried using the example. – Incredible Jan 30 '18 at 06:03
  • Joining @Saruman 's question: why does MyTool.exe need to get this argument with double-back-slashes? Isn't it easier to do such string operations inside MyTool.exe? – felix-b Jan 30 '18 at 06:15
  • @felix-b Because I need the variable like `$(SolutionDir)` and `` provided by Visual Studio. It is not a fixed value and `$(TargetDir)` will be passed as an argument. – zwcloud Jan 30 '18 at 06:25
  • AFAIK there should be no problem passing $(SolutionDir) as is in an argument to your tool. Have you tried passing it as is? – felix-b Jan 30 '18 at 06:27
  • @felix-b I need to use mytool.exe in the post-build event. – zwcloud Jan 30 '18 at 06:29
  • Obviously, my question was why do you think that escaping is necessary at all? Is MyTool.exe a program that you wrote? If yes, in this program try printing the value of the first argument -- isn't it OK without escaping? What is the problem exactly? – felix-b Jan 30 '18 at 06:38
  • @felix-b Number of argments got inside mytoo.exe is incorrect. There should be four but there is only one(the entire line). – zwcloud Jan 30 '18 at 06:43

2 Answers2

2

How to escape backslash in $(SolutionDir) in a VS project file?

Not sure why you want to replace the "\" with "\\" in the $(SolutionDir). That because this property is common macros for build commands and properties, You can use these macros anywhere in a project's Property Pages dialog box where strings are accepted.

But if you insist on replacing it, you should replace it with $(SolutionDir.Replace('\', '\\')) rather than $(SolutionDir.Replace('\\', '\\\\')). Because the path in the $(SolutionDir) is D:\Some\MySystem\, Only one backslash. When you replace it with double backslashes, MSBuild could not find the double backslashes in the $(SolutionDir).

So the scripts should be:

  <PropertyGroup>
    <EscapedSolutionDir>$(SolutionDir.Replace('\', '\\'))</EscapedSolutionDir>
    <EscapedTargetDir>$(TargetDir.Replace('\', '\\'))</EscapedTargetDir>
  </PropertyGroup>

Then I use a target to output the escaped value in the EscapedSolutionDir and EscapedTargetDir, both those value were escaped:

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Message Text="$(EscapedSolutionDir)" Importance="high">
    </Message>
    <Message Text="$(EscapedTargetDir)" Importance="high">
    </Message>
  </Target>

The output:

enter image description here

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • I have already tried what you typed and it also doesn't work. Let's discuss about it later. I'm a little busy now. – zwcloud Jan 30 '18 at 06:48
  • Thanks for the screenshot. Upvoted. I'll try that later. – zwcloud Jan 30 '18 at 06:56
  • @zwcloud, It does not matter. You can reply me when you free. I output the escaped value, found it was changed to "\\", you can check your escaped value with this method. If you find it already changed to "\\", you problem may not about change "\" to "\\", it may be for other reasons that you can not run your tool.exe. – Leo Liu Jan 30 '18 at 07:01
  • It doesn't work on the second variable `$(EscapedTargetDir)`. I mean the second message wasn't printed in the output window. I have lost my confidence in MSBuild. I will parse [`commandline`](https://msdn.microsoft.com/en-us/library/system.environment.commandline) myself. – zwcloud Jan 30 '18 at 10:48
  • [This is why I want to escape the backslash.](https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/) – zwcloud Jan 30 '18 at 10:50
  • @zwcloud, if the `$(SolutionDir)` works fine but `$(EscapedTargetDir)`, you can use `$(SolutionDir)`$(ProjectName)\\bin\\Debug\\ replace. – Leo Liu Jan 30 '18 at 11:33
  • I mean I didn't see the second red-underlined message. – zwcloud Jan 30 '18 at 11:35
  • @zwcloud, yes, I know. What is your test target in your project? Have you set the test line ` `? If yes, what is the output log? – Leo Liu Jan 30 '18 at 12:12
0

Be aware that some Environ Vars finish with a backslash.... add a "." and then when using them add the "\" for example I was trying to get a meesage (#pragma message) with a file path and name...

I did it like this: <PreprocessorDefinitions>INT_DIR=$(IntDir.Replace('', '\')).;%(PreprocessorDefinitions)</PreprocessorDefinitions>

And then

#define MyFile "File.ext"

#pragma message ( TO_STR(INT_DIR) "\\" MyFile "(0) : MESSAGE: File Included")