37

In a Setup project the executable files such as ".exe , .dll , .js , .vbs" are acceptable but there is no way to run a .bat file in a Custom Action.

The question is how to run the *.bat files during installation?

Hakan Fıstık
  • 11,376
  • 8
  • 74
  • 105
mammadalius
  • 2,955
  • 5
  • 34
  • 44

4 Answers4

62

Well, after much searching and trial and error I have solved this. I'm not sure if this is the best way, but it works.

Here's the scenario: I have an application I would like to deploy via a Visual Studio Setup project. In addition to my application files, I would like to create a subdirectory in the target directory that contains a batch (.bat) file. I would like this file to run at the end of the installation process.

Here's what you do:

  1. Create a setup project and configure as you normally would, including the subdirectory in which you'll place your batch file (you can just place it in the Application Folder directly if you don't want it in a subdirectory).
  2. In the "File System" view (right-click on the project in Solution Explorer->View->File System), add the batch file you want to execute and cmd.exe (C:\Windows\System32\cmd.exe)
  3. Open the "Custom Actions" view (right-click on the project in Solution Explorer->View->Custom Actions)
  4. Right-click on "Commit" and choose "Add Custom Action"
  5. Navigate to and select cmd.exe.
  6. Open the properties panel for the newly created custom action.
  7. Delete /Commit from the Arguments property.
  8. Enter: /c "[TARGETDIR]subdirectoryname\batchfile.bat" in the Arguments property, where subdirectoryname should be replaced by the name of your subdirectory (if you put the batch file in a subdirectory like I did... if you didn't, the value should be /c "[TARGETDIR]batchfile.bat") and batchfile.bat should be the filename of your batch file.

That's it. The batch file will now be executed once the rest of the installation process is completed.

Here's an example for the sake of clarity:

My batch file: blah.bat
My subdirectory: mydir

The value of the Arguments for my custom action targeting cmd.exe would then be

/c "[TARGETDIR]mydir\blah.bat"

Hope that helps someone!

Brian Mulcahy
  • 1,373
  • 1
  • 14
  • 25
  • 6
    As an addendum, I found that running the packaged cmd.exe (as opposed to cmd.exe in the System32 directory) turns all the error messages from an informative statement to things like "The system cannot find message text for message number 0x8". To get around this, you can (if you know for sure that there will exist cmd.exe in System32 on the target computer) use `/c cmd.exe /c "TARGETDIR]subdirectoryname\batchfile.bat"`. This will cause the packaged cmd.exe to invoke the native cmd.exe on the target computer, which will give the right error messages. – Brian Mulcahy Jun 09 '11 at 22:01
  • 1
    Warning: this method doesn't work if the setup is created under Windows 10 and executed under Windows 7 !! – Lumo Mar 09 '16 at 14:31
  • @Lumo: just for info; the option with the `vbs` works independent of the OS. – Stefan Jul 17 '16 at 13:28
6

One other way to reach the same result is put a .vbs file in custom actions that runs the correspondent .bat file. The following code is the "RunRegisterComponents.vbs" I put in setup application folder. Of course I put [TARGETDIR] as .vbs parameter in Visual Studio property window.

dim WshShell
Set WshShell = CreateObject("WScript.Shell")

' Read the "CustomActionData" property holding the install directory.
dim programDir
programDir=  property("CustomActionData")

' Make the batch full file name and parameter
commandString = chr(34) & programDir & "RegisterComponents.bat" & chr(34) & " " & chr(34) &
programDir& chr(34)

' Set the current directory
WshShell.CurrentDirectory = programDir

' Run batch.
ret = WshShell.Run (commandString, 0, 0)

That is as I set my custom actions:

enter image description here

I hope this can help you!

Wolf
  • 8,482
  • 7
  • 48
  • 92
Massimo
  • 117
  • 1
  • 4
  • I still think this is the better option since it doesn't dependent on `cmd.exe`. – Stefan Jul 17 '16 at 13:27
  • You are setting `WshShell.CurrentDirectory` to the installation directory (`[TARGETDIR]`), isn't it redundant to place `programDir` in the `commandString` before `RegisterComponents.bat`? – Wolf Dec 12 '16 at 13:10
  • 2
    Im using this method but I receive an error with the following message: "A script required for this install to complete could not be run" Anybody had this issue before? – Oscar_sgc Jan 28 '19 at 20:23
5
  1. Check this article (article is deprecated), even though it is in VB.NET it applies to C# as well. The most important part is (translated to C#) creating a new Class Library, and adding a new Installer Class with the following content: As stated in the article you can then create a new custom action with a reference to your just created project.

    override void Commit(IDictionary savedState)
    {
         base.Commit(savedState);
         System.Diagnostics.Process.Start("myApp.bat","your bat arguments");
    }
    
  2. Now we are adding batch file to your installer project. Create a setup project and configure as you normally would, including the subdirectory in which you'll place your batch file (you can just place it in the Application Folder directly if you don't want it in a subdirectory).

  3. In the "File System" view (right-click on the project in Solution Explorer->View->File System), add the batch file you want to execute.

  4. Build the installer project.

karthik
  • 16,456
  • 70
  • 72
  • 119
Y P
  • 574
  • 7
  • 10
0

If you are trying to run a batch file that have relative paths during the installation process, that will fail for sure. That's because the batch file will take into account the directory where the installer is running, and not where the files were being installed. Use installer builders that copies batch files into temporary directory.