Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute MSBuild from Delphi?

I'm working on automating our software's build / deploy process. One major piece of this is executing msbuild to compile multiple Delphi projects.

Following numerous resources such as this one, I can do it successfully from the RAD Studio Command Line (which is simply calling rsvars.bat to set some environment variables). However, when trying to automate both this batch file and the msbuild command from Delphi, I cannot figure out how to proceed.

The key of the issue is that the batch file and the actual msbuild command are two entirely separate commands - although they need to be run together under the same environment. I found this question somewhat related, but I don't see a clear answer for my scenario.

How can I execute msbuild from Delphi while first preparing it with the environment variables as found in rsvars.bat?

like image 593
Jerry Dodge Avatar asked Dec 11 '22 16:12

Jerry Dodge


2 Answers

As this answer showed, you can run cmd.exe itself with command-line parameters to execute commands.

Per the cmd.exe documentation:

Syntax

cmd [/c|/k] [/s] [/q] [/d] [/a|/u] [/t:{<B><F>|<F>}] [/e:{on|off}] [/f:{on|off}] [/v:{on|off}] [<String>]

Parameters

/c
Carries out the command specified by String and then stops.
...
<String>
Specifies the command you want to carry out.
...

Remarks

  • Using multiple commands

    To use multiple commands for <String>, separate them by the command separator && and enclose them in quotation marks. For example:

    "<Command>&&<Command>&&<Command>"
    
  • Processing quotation marks

    If you specify /c or /k, cmd processes the remainder of String, and quotation marks are preserved only if all of the following conditions are met:

    • You do not use /s.

    • You use exactly one set of quotation marks.

    • You do not use any special characters within the quotation marks (for example: & < > ( ) @ ^ | ).

    • You use one or more white-space characters within the quotation marks.

    • The String within quotation marks is the name of an executable file.

    If the previous conditions are not met, String is processed by examining the first character to verify whether it is an opening quotation mark. If the first character is an opening quotation mark, it is stripped along with the closing quotation mark. Any text following the closing quotation marks is preserved.

So try using CreateProcess() or ShellExecute/Ex() to run an instance of cmd.exe with these parameters:

cmd.exe /C ""<path>\rsvars.bat" && msbuild "<path>\project" <msbuild parameters> ..."

Alternatively, you can have your app load rsvars.bat and parse out the values it defines (or just define the values in your own code), and then execute msbuild using CreateProcess(), passing the desired environment variables to its lpEnvironment parameter. This way, you do not need to actually execute rsvars.bat at all.

like image 140
Remy Lebeau Avatar answered Dec 20 '22 09:12

Remy Lebeau


Another way which works is to put both commands together into another new batch file. This also allows you to build multiple projects using the same environment. For example DoBuild.bat with the following contents:

call "C:\Program Files (x86)\Embarcadero\Studio\17.0\bin\rsvars.bat"
msbuild "<path>\MyProject.dproj"
msbuild "<path>\MyOtherProject.dproj"
msbuild "<path>\YetAnotherProject.dproj"

Then, just execute your batch file:

Cmd.exe /K "<path>\DoBuild.bat"
like image 40
Jerry Dodge Avatar answered Dec 20 '22 10:12

Jerry Dodge