PS2EXE-GUI: "Convert" PowerShell Scripts to EXE Files with GUI

Overworking of the great script of Ingo Karstein with GUI support. The GUI output and input is activated with one switch, real windows executables are generated. With Powershell 5.x support and graphical front end.

PS2EXE-GUI.zip
 
 
 
 
 
4.7 Star
(35)
33,469 times
Add to favorites
7/1/2019
E-mail Twitter del.icio.us Digg Facebook
Sign in to ask a question


  • Output from called vbs
    2 Posts | Last post August 17, 2018
    • Hi,
      I'm calling a vbs file though
      Invoke-Command -ScriptBlock { cscript "file.vbs"}
      
      In "console" mode, is there a way to get the standard output from file.vbs?
      Without "compiling" the ps1, i see the output from the vbs.
      
      Thanks, Nestor.
    • Hello Nestoter,
      
      I tried your sample code and got the Standard output of a vbs file shown in the compiled script.
      
      May you have an other error? Can it be your vbs file is not found since you don't supply a path to it?
      
      Greetings
      
      Markus
  • Included ps1 files
    3 Posts | Last post August 07, 2018
    • Hi,
      
      Works almost perfectly for what I need, just 1 question:
      
      Is there a way for the script to automatically add the code from imported scripts within the main script?
      
      I.e. I have a functions.ps1 file that gets imported at the top of the main file. This file will also import ps1 files depending on the function being called. This is being include via the following line:
      
      . "..\Includes\functions.ps1"
      
      If I leave this line in, I get an error stating that the command is not recognised.
      
      Any ideas?
      
      Thanks,
      Joe
    • Hello Joe,
      
      dot sourcing works fine with PS2EXE. As you are using a relative path please check that the current directory is what you expect it to be.
      
      You might use a path relative to the compiled script with:
      
      f ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
      { $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
      else
      { $ScriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) }
      . "$Scriptpath\..\Includes\functions.ps1"
      
      (see "Remarks" sction for an explanation)
      
      Greetings
      
      Markus
      
    • Hi Markus,
      
      Thank you for your response, I actually already saw that piece of code, and was using it. For anyone that may have the same issue as I was, I created a script called "combine.ps1", with the following code:
      
      $includes = @()
      $includes = "..\Includes\file-01.ps1","..\Includes\file-02.ps1","..\Includes\file-03.ps1"
      Clear-Content .\complete-script.ps1
      
      Foreach ($include in $includes) {
      	$content = Get-Content $include | Where { $_ -notmatch "^\." }
      	$content = $content | Where { $_ -notmatch "^\# SIG" }
      	Add-Content .\complete-script.ps1 $content
      }
      
      .\PS2EXE-GUI\ps2exe.ps1 -inputFile ".\complete-script.ps1" -outputFile ".\complete-script.exe" -noConfigFile -credentialGUI
      Remove-Item ".\complete-script.ps1" -Force
      
      
      It's not ideal, as you have to specify the files in the array in the same order as what they appear in the script, but gets the job done.
      
      An improvement to this would be to add an "If" statement that finds the lines starting with "." and then automatically import that script in to "complete-script.ps1" file. Obviously, you would need to search recursively for dot sourced scripts to import...
      
      Thanks,
      Joe
  • -noConsole Secure input
    3 Posts | Last post July 29, 2018
    • Hi Markus,
      
      First thanks for this wonderful tool. It makes life so easy.
      
      I am converting a script to exe which reads host as secure string. On converting it to exe with -noConsole, the windows form box show text as "Secure Input". I was hoping it to use the message text from the script like "Enter your password". Any way to fix this? Am I doing something wrong?
    • Hello pghack,
      
      thank you for pointing to this bug. I will release a new version of PS2EXE soon with this error fixed.
      
      Greetings
      
      Markus
      
    • Hello pghack,
      
      I released the new version 0.5.0.12 today that shows the message text for Read-Host.
      
      Greetings
      
      Markus
  • The form doesn't show correctly
    3 Posts | Last post July 28, 2018
    • Hello Markus.
      I have written a ps1 script that show a form containig a label with some text.When i execute ps1 everything is Ok, but if i run exe file, the label is white, overlying the form background and it has no text.I have compiled the script with -x32 -noConsole -Mta -noConfigfile -runtime40 parameters.
      
      Here is the script:
      
          Function Generate-Form ($_mesage){
          Add-Type -AssemblyName System.Windows.Forms
      
          # Build Form
          $objForm = New-Object system.Windows.Forms.Form
          $objForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D
          $objForm.ControlBox = $false
          $objForm.BackColor="LightBlue"
          $objForm.StartPosition = "manual"
          $objForm.Location = New-Object System.Drawing.Size(520,320)
          $objForm.AutoSize = $True
          $objForm.AutoSizeMode = "GrowAndShrink"
      
          # Add Label
          $objLabel = New-Object System.Windows.Forms.Label
          $objLabel.Text = $_mesage
          $objLabel.AutoSize = $True
          $objLabel.Location = New-Object System.Drawing.Size(0,0)
          $objLabel.Font = New-Object System.Drawing.Font("Times New Roman",18,[System.Drawing.FontStyle]::Italic)
          $objLabel.ForeColor = "BlueViolet"
          $objLabel.BackColor = "LightBlue"
          $objLabel.TextAlign = "MiddleCenter"
          $objForm.Controls.Add($objLabel)
          $objForm.Show()| Out-Null
          
          # wait 3 seconds 
          Start-Sleep -Seconds 3
          
          # destroy form
          $objForm.Close() | Out-Null
          }
      
          Generate-Form("Operation Completed")
    • Hello Catalin Ivan,
      
      please remove the Parameter -MTA since Winforms may not work correctly in Multi-Threaded Appartment, you may see here:
      https://stackoverflow.com/questions/4659220/why-are-winforms-applications-stathread-by-default
      or here:
      https://blogs.msdn.microsoft.com/jfoscoding/2005/04/07/why-is-stathread-required/
      
      Greetings
      
      Markus
    • Thank you Markus,
      
      It works great!
  • "ExternalScript"
    2 Posts | Last post July 27, 2018
    • Please clarify the "ExternalScript" string in the section:
      
      if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
      { $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
      else
      { $ScriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) }
      
      Am I specifying the Executable generated or any single file residing in the path I'm trying to retrieve?
    • My mistake, it works without modifying the string. 
  • Icon isn't showing in taskar and output box.
    3 Posts | Last post July 26, 2018
    • Hello Markus.
      
      I compile ps1 file with an icon file successfully. But when I executes it with some outputs, it's not show the compiled icon in taskbar and in message box.
      
      Please modifing the script to get the compiled icon appear in both taskar and message box, Markus :D
      
      Maybe adding an option to disable the `-extract:path` feature.
      
      Is there any script to minifing .PS1 source code?
      
      Greetings
      Minh Cường
      
    • Sorry.
      The icon is showing up correctly in Taskbar after I resized it to 48x48 dimension.
      Maybe icon in the title bar of message box is not necessary.
      
    • Hello Minh Cường,
      
      it is not the intention of PS2EXE to hide the source code but to make easy-to-use executables from powershell scripts, so I would not like to see the option to disable the extraction parameter (another reason is that there is no encryption in PS2EXE, just encoding to prevent special characters from breaking the script. Disabling the extract option would not really prevent curious eyes from seeing the script).
      
      If you want to disable this Option anyway, you can do it yourself with the following steps:
      1. Make a security backup of PS2EXE.ps1
      2. Open ps2exe.ps1 in your favorite text Editor (or Notepad)
      3. Search for 's.StartsWith("-extract", StringComparison.InvariantCultureIgnoreCase)' (without the single quotes)
      4. Replace this expression with 'false' (without the single quotes)
      5. Save ps2exe.ps1
      From now on compiled scripts does not have the extract option anymore.
      
      
      I do not know any minifying tool for powershell, please ask your favorite search engine.
      
      Greetings
      
      Markus
      
  • compiled Process does not exit
    3 Posts | Last post July 22, 2018
    • Hi Markus,
      
      Thanks for this great utility. It is working marvellously.
      
      There is just one matter disturbing my peace. I wrote a multi runspace WPF gui according to Foxdeploy's blog (https://foxdeploy.com/2016/05/17/part-v-powershell-guis-responsive-apps-with-progress-bars/ ). That is working all well. However, if I compile my gui, the process.exe remains active after closing the window. I have to kill it manually to get rid of it. 
      
      Have you got any ideas, why this is so and how I could prevent it?
      
      Best
      Stefan the Scotlandhiker
      
    • Sorry I forgot. My parameters are like that:
      .\#ps2exe.ps1 -inputFile .\TMMT4K.ps1 -outputFile .\TMMT4K.exe -runtime40 -x64 -Mta -noConsole -iconFile .\Scots.ico -noConfigfile
      
    • Hello Stefan,
      
      it took me some time and brain to investigate this!
      
      There is a continuing bug or better said leak in the script of Foxdeploy's blog. Runspaces are opened but never closed.
      Powershell.exe closes those runspaces forcefully, PS2EXE waits (infinitely) for them to close. To see what I mean start the example from Foxdeploy with
      powershell.exe <PATH>\Powershell_GUI_Template.ps1
      (please provide the correct <PATH>)
      
      There are two ways to correct this
      
      1. Remove all appearances of 
        $newRunspace.ThreadOptions = "ReuseThread"
      With this change PS2EXE will close runspaces forcefully.
      
      2. Correctly close the runspaces after use
      This is more complicated, for the example "Powershell_GUI_Template.ps1" on Foxdeploy you have to insert
      	$runspace.Powershell.Runspace.Close()
      after line 82 (= $runspace.powershell.dispose())
      
      Change line 169 
        $jobCleanup.PowerShell.Dispose()      
      to the three lines
        $jobCleanup.PowerShell.EndInvoke($jobCleanup.Thread)
        $jobCleanup.PowerShell.Dispose()      
        $jobCleanup.PowerShell.Runspace.Close()
      
      Append 
        $psCmd.EndInvoke($data)
        $psCmd.Dispose()
        $psCmd.Runspace.Close()
      at the end after 
        $data = $psCmd.BeginInvoke()
      
      (there is still a "runspace leak" left when closing the window while Update-Window is working, you have to fix it yourself)
      
      Greetings
      
      Markus 
      
  • DOS Errolevel
    2 Posts | Last post July 22, 2018
    • Thanks for your great work!
      I've produced an .exe of a simple script, but I noticed that the dos %errorlevel% is always 0 if the script runs correctly,even when the PS1 is just
      invoke-expression "cmd /c exit 1"
      
      is there a way for the built .exe to return the last exit code? (%errorlevel%) ?
      Many thanks!
    • Hello MKz991,
      
      as in powershell.exe there is no automatic return of the last exit code in PS2EXE to the calling shell. According to powershell scripts you have to use
        exit $LASTEXITCODE
      as last command in your script to accomplish this.
      
      Greetings
      
      Markus
      
      
  • Hardcoded variables
    3 Posts | Last post July 22, 2018
    • Hello Markus,
      
      I have hardcoded variables in the compiled .ps1, like:
      $scRoot = $PSScriptRoot
      $csvsource = $scRoot + "\ISO.csv"
      
      The complied program now it reference the $csvsource to: C:\ISO.csv
      
      What could be the solution? How can I add the variable into the .exe.config file?
      
    • isn't that written in the readme?
      
      "
      You can retrieve the script/executable path independant of compiled/not compiled with the following code (thanks to JacquesFS):
      
      if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
      { $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
      else
      { $ScriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) }
      "
    • Hello Thomeee,
      
      MKz991 is right, please see the "remarks" section of this web page for a description and a solution.
      
      Greetings
      
      Markus
  • Compiled with -NoConsole but there are some windows still flashing.
    5 Posts | Last post July 15, 2018
    • Hi Marcus.
      
      Right after I execute the compiled file after compiling with -NoConsole switch, I see some flashing windows and flashing icons on taskbar too.
      How to absolutely hide all windows?
      
      Greetings
      Minh Cường
    • Hello Minh Cường,
      
      I can not reproduce this behaviour. When I compile my scripts with -noConsole, there are no windows or taskbar icons appearing. Is it possible that you start something in your script needing or generating a window? Does this happen with empty scripts too?
      
      Greetings
      
      Markus
    • Hello Markus.
      
      You can test this behavior by compiling 2 examples code's line below:
      
      Example with CMDlets (compiling with -NoConsole):
      $Null = Invoke-WebRequest -uri "http://example.com/" -disableKeepAlive
      
      Example with CMD commands (compiling with -NoConsole -RequireAdmin):
      $Null = mountvol.exe x: /s
      
    • Hello Minh Cường,
      
      Invoke-WebRequest shows a progress bar, which is displayed in a new window in -noConsole mode. If you don't want this window, disable displaying of progress bars with:
      
      $ProgressPreference = 'SilentlyContinue'
      $Null = Invoke-WebRequest -uri "http://example.com/" -disableKeepAlive
      $ProgressPreference = 'Continue'
      
      mountvol.exe needs a command shell to run so it starts its own if there is no shell present. This is the window that appears for a very short time. The solution is to start mountvol.exe (and its shell) hidden:
      
      $Null = Start-Process mountvol.exe -ArgumentList 'x:','/s' -WindowStyle Hidden
      
      
      Greetings
      
      Markus
      
      
    • Thanks very much for your advice, Markus.
      
      Greetings
      
      Minh Cường
      
61 - 70 of 143 Items