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,463 times
Add to favorites
7/1/2019
E-mail Twitter del.icio.us Digg Facebook
Sign in to ask a question


  • Runtime Error on Azure VM
    2 Posts | Last post December 08, 2018
    • Have been running my exe on Windows 2016 Azure B1ms VM successfully for a couple of weeks when suddenly this rather ugly runtime error cropped up:
      
      Faulting application name: MSGFX.exe, version: 8.1.0.0, time stamp: 0x5beb4362
      Faulting module name: mscoreei.dll, version: 4.7.2623.0, time stamp: 0x5a1f657c
      Exception code: 0xc00000fd
      Fault offset: 0x000000000000ac16
      Faulting process id: 0x42c
      Faulting application start time: 0x01d48d90e9c1f73c
      Faulting application path: C:\msgsvr\MSGFX.exe
      Faulting module path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscoreei.dll
      Report Id: 5d859db4-d2f3-4207-b065-b405813d6b25
      
      The .ps1 always ran fine without error.
      
      Cheers, Simon
    • Hello Msgwrx,
      
      exception code 0xc00000fd means "Stack overflow exception". It can be very hard to find the reason for this error, often it results of non closed ressources or recursions that unexpectedly do not stop.
      
      I guess you have no choice but to check the script and maybe monitor it.
      
      Greetings
      
      Markus
  • Message Box on top
    8 Posts | Last post November 14, 2018
    • Hi,
      
      Thanks for your excellent work. 
      
      I have compiled my script and it all works perfecty (so far!) but is there any way of making any message boxes come to the fore? They appear in the background somewhere and I have to either Alt-Tab to them or click on the .Net icon on the task bar.
      
      I'm sure this is quite easy and I'm just not looking in the right place.
      
      Thanks for your help.
      
      Mull1001
    • Hello Mull1001,
      
      I've seen the haviour you describe before. It seems that the windows appear in the background after a new independant window has been opened in the compiled script (maybe through a Shell or a credential window).
      
      An example for this is this command:
        ipconfig | Out-String
      
      I do not understand the reason for this now and need some time to investigate.
      
      Greetings
      
      Markus
      
    • Hello Mull1001,
      
      it was a hard job to investigate this issue and to find a solution.
      
      First, what is happening when for example the following command is executed in a compiled script:
        ipconfig | Out-String
      
      Windows opens and activates a window for a new instance of cmd.exe that is necessary to execute ipconfig.exe. After completing the command cmd.exe and its window is closed. Windows tries to activate the parent window of the closed window, but since the compiled script has no window at this time, the parent window of the compiled script - most of the times the window of Explorer or Powershell - is activated.
      When the compiled script opens a window afterwards it is opened behind the parent's window.
      
      I've made several attempts to bring the compiled script's window to the front by calling the Win32 API (with SetForegroundWindow, ShowWindow...), but the best I got was an orange flashing icon in the task bar (if someone has an idea how to manage that help would be appreciated).
      
      The only solution I found is to generate an (invisible) window in the script before an external window is opened.
      Returning to the example above you get an activated window in front with:
      
      	Add-Type -AssemblyName System.Windows.Forms
      	$DummyForm = New-Object System.Windows.Forms.Form
      	$DummyForm.Opacity = 0
      	$DummyForm.ShowInTaskbar = $FALSE
      	$DummyForm.Visible = $TRUE
      
      	ipconfig | Out-String
      
      	$DummyForm.Close()
      
      I'm sorry I have no better solution for you. Maybe you or someone else has another better idea?
      
      Greetings
      
      Markus
      
    • Hi Markus,
      
      That might not be a perfect solution but it's good enough for my needs and fixes my issue.
      
      Your efforts are very much appreciated.
      
      Thanks,
      Mull1001
    • Hello Mull1001,
      
      I build the pseudo command $Host.UI.RawUI.FlushInputBuffer() that creates the invisible window in -noConsole mode in the new version 0.5.0.13 of PS2EXE. A following call closes the invisible window (.. the next call opens again and so on...).
      The example above will work with:
      
        $Host.UI.RawUI.FlushInputBuffer()
        ipconfig | Out-String
        $Host.UI.RawUI.FlushInputBuffer()
      
      Greetings
      
      Markus
      
      
    • Hi,
      I spent so long time to purge all my 500 lines script of messages box.
      I discovered that it comes any time an output value is written (as write-host,...) and errors handling.
      So, I decided to filter any possibility to write and all errors are redirected in a .log with a function LogWrite.
      I would say: so long you have returns in your ISE prompt, so long you 'll keep messages box with the .exe.
    • Hello E.Drot,
      
      I must admit I don't really understand your question.
      
      Is it this that you are complaining about (from the Description text):
      "...every output and input function like Write-Host, Write-Output, Write-Error, Out-Default, Prompt, ReadLine to use WinForms message boxes or input boxes automatically when compiling a GUI application"?
      
      When compiling with -NoConsole every output is shown as a message box, if you want to prevent this you might pipe your commands with output to Out-Null or catch the output in a variable.
      
      Greetings
      
      Markus
    • Hello Markus,
      
      that was not a question, just a remark: I had to fix up the output messages send in an output box to screen the result of a Get-ADcomputer before the user is able or not (linked to the result of ADquest) to press a button and launch a Set-ADcomputer. Output messages must be screened and written in logfiles.
      I also had to fix up credentials returns (bad account or password,...).
      
      Now, it works perfectly.
      
      Thanks,
      
      Emmanuel
  • Run executable as a service
    2 Posts | Last post November 13, 2018
    • Dear Markus, excellent piece of work..!
      
      Application .exe works like a dream in console mode (GUI not required).
      
      Wondered if there's anything special needed to run .exe as a service..?
      
      Cheers, Simon
      (I tried, wouldn't start, not surprised)
      
      
    • Hello Msgwrx,
      
      there are some special requirements for a process that is supposed to be used as a service. Those are not implemented in PS2EXE.
      
      Maybe you can compile a script that is capable to be run as a service, e.g. the script from https://msdn.microsoft.com/en-us/magazine/mt703436.aspx might work wth some customizings.
      
      Greetings
      
      Markus
  • Retrieve exe name
    2 Posts | Last post October 27, 2018
    • Hello Markus,
      
      While I'm running the .exe file, is there a way to retrieve its actual name?
      
      I'd like copy the .exe file to a specific location at the end of the process.
      But if the .exe was renamed before running, [Copy-Item ".\MyFile.exe" "$Specific_Locaction"] won't work. (I use runtime20)
      
      Thanks.
    • Hello AG_G1,
      
      when I didn't forget one you have three methods to get the name of the executable:
      
      1. [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
      retrieves the name of the executable including the full path
      
      2. [Environment]::GetCommandLineArgs()[0]
      retrieves the name of the executable most of the times including the full path
      
      3. [System.Diagnostics.Process]::GetCurrentProcess().ProcessName
      retrieves the name of the executable without path and without the extension ".exe"
      
      
      When called in a not compiled script the name of the powerShell is returned.
      
      
      Greetings
      
      Markus
      
      
  • ActiveDirectory module on network share
    2 Posts | Last post October 23, 2018
    • Hi
      
      I just ran into something peculiar that I think must be a bug.
      
      Created an exe with the following options~
      .\ps2exe.ps1 -inputFile $InputFile -outputFile $outputFile -noConsole -iconFile $iconFile -title $title -description $description -company $company -version $version -noConfigFile
      
      It opens up a simple Windows form with two textboxes and a run button.
      The run button basicly runs the following get users info and export to csv~
      	Get-ADUser -Filter * -Properties * -SearchBase $SearchOU | `
      	where {(Get-Date).AddDays($InputDays) -le $_.whenCreated } | `
      	select sAMAccountName, name, mail, title, division, department, whenCreated | `
      	
      	Export-Csv -Path $ExportCSVPath -Encoding UTF8 -NoTypeInformation
      
      The exe file will run perfectly anywhere on the C:\ drive, but if you have a mounted network drive, in our case Z:\ Import-module ActiveDirectory will fail to load with the following error message "Unable to contact the server. This may be because this server does not exist, it is current down, or it does not have the Active directory Web Service running.
      
      
    • Hello Bjørn,
      
      I tried your code sample on a local drive and a mounted drive: it worked fine in both cases.
      
      Have you checked if there is a problem with elevation (mounted drives are in general not visible in an elevated process)? Do you have AppLocker or Software Restriction Policies activiated that may prevent your script from running? Is your script running in PowerShell Constrained Language Mode? Do you have Share Hardening activated on the server that serves the mounted drives?
      
      Greetings
      
      Markus
      
      
  • Ohne Progress zu verwenden, poppt ein leeres Fenster mit dem Titel progress auf
    3 Posts | Last post October 21, 2018
    • I wrote a script that is displaying it's own two forms. If I run the script in Powershell ise everything works like expected, no output is written into the console. If I compile it with a console output, it works, too. BUT if I compile it with -noconsole, a window pops up several times very shortly - like a blinking. Using a screen shot program I discovered, that it is an empty window with the title progress. I am not using ANY progress related function.
      
      Is this a bug? I am using Windows 10 1809. How can I prevent this window flickering?
      
    • Hello CHBWien,
      
      when modules are loaded progress bars are displayed in powershell. In console mode they may appear and disappear so fast that you do not notice them.
      
      Try preventing any progress bar with the following command at the beginning of your script:
      
      $ProgressPreference = 'SilentlyContinue'
      
      Greetings
      
      Markus
      
    • Hi Markus,
      
      great advice. Works like a charm.
      
      Never realized, that progress bars appear on their own...
      
      THX!
      
      Christian
  • Reading from registry
    3 Posts | Last post October 17, 2018
    • Hi,
      
      I've got a PowerShell script which writes/reads from registry.
      
      write to registry:
      New-ItemProperty -Path $global:registryPath -Name $name -Value $global:deadline -PropertyType String -Force | Out-Null
      
      writes a date to reg value "ignoreTo"
      
      read from registry:
      $ignoreTo = (Get-ItemProperty $global:registryPath | Select-Object -ExpandProperty ignoreTo | Out-String) -replace "`n|`t|`r",""
      
      $ignoreTo (e.g. 17.10.2018) is a date which gets compared against $today (e.g. 16.10.2018)
      
      if ($today -gt $ignoreTo){
      ...
      }
      
      Both parts are working when I run the script as PowerShell. When I convert it to exe, the read part (or the comparision) doesn't, the if-condition allways runs.
      
      Any ideas where to start?
      
      Thx,
      Tony
      
    • I converted with:
      
      .\ps2exe.ps1 -noconsole -inputfile D:\PS\Check_DA_VPN\check_status.ps1 -outputfile D:\PS\Check_DA_VPN\UpdatePopup.exe –noconfig
    • Hello t_ny,
      
      your code fragment works fine for me (in one script). But I do not know how you get and convert your date values.
      
      Can it be that you try to use global variables to hand a value to different scripts? Compiled scripts do not know global variables, they only know variables that are defined in the executable.
      
      Greetings
      
      Markus
  • $MyInvocation - ScriptPath not returning correct path
    5 Posts | Last post October 03, 2018
    • I am running script from following location
      C:\Users\testuser\Downloads\PS2EXE-GUI\FIleShare
      
      IN this location I have one file called i.e. "Assessment.xml"
      
      As you suggested I used following
      if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
      { $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
      else
      { $ScriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) }
      
      Then
      
      [xml]$xmlParameterAttribute = Get-Content "$ScriptPath\Assessment.xml"
      
      Without compling this code it is working fine, $scriptpath is correctly show path as mentioned above.
      
      But when I compile the code and run the code, it is coming as "c:\asessment.xml" instead of "C:\Users\testuser\Downloads\PS2EXE-GUI\FIleShare\asessment.xml".
      
      Am I missing anythig?
      
      I also used script path as 
      if ($hostinvocation -ne $null)
      {
           $ScriptPath=Split-Path $hostinvocation.MyCommand.path
      }
      else
      {
           $ScriptPath=Split-Path $script:MyInvocation.MyCommand.Path
      }
      
      But no luck, not sure what I am missing here.
      
      Avian
    • Hello Avian,
      
      I used the snippet you posted to check the issue. In my tests everything worked fine.
      
      The variable "$hostinvocation" is no standard variable, may you tell what version of PowerShell and Environment/Frameworks you use?
      
      Greetings
      
      Markus
    • HI Markus
      
      I am testing in PowerShell version 2.0.
      
      Surprisingly if I run as script it works, but when I run as exe it wont work.
    • Hallo Avian,
      
      I made a test on virtual machine with Windows XP and PowerShell 2.0, still everything works fine. Are you sure there is no typo in your script?
      
      
      Greetings
      
      Markus
    • Hello Avian,
      
      I got it. When you call the compiled script in a cmd.exe (and not in Powershell) without providing a path, [Environment]::GetCommandLineArgs()[0] returns $NULL.
      
      Please use the following code to prevent this (I updated the "Remarks" section of this web page too):
      
      if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
      { $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
      else
      { $ScriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) 
        if (!$ScriptPath){ $ScriptPath = "." } }
      
      
      Greetings
      
      Markus
      
  • Getting strange parsing errors running after compilation?
    2 Posts | Last post September 15, 2018
    • Something in my script seems to be trigger runtime compilation errors after the exe is created.
      
      I'm guessing it's an issue in the encoding, or possibly special characters surviving the extraction from exe process?
      
      My script is here:  https://github.com/keylimesoda/MaddenToCSV
      
      Output when running exe is parsing errors at line 90, line 224, etc.
    • Hello Ric,
      
      I compiled your script but running does not succeed because of the usage of the variables $PSSCriptRoot and $myInvocation.MyCommand.Definition which are not present in compiled scripts (as they are no scripts anymore).
      
      See my explanation in the REMARKS section of this web page. Maybe that helps you.
      
      Greetings
      
      Markus
  • Get-Credential not returning $null when cancelled
    5 Posts | Last post September 11, 2018
    • Hi,
      Really great script! Had no problems until I tried to work with Get-Credential. I store a Password as an XML file. If the user accidently clicked the "Change Credentials" Button, he should be able to abort by clicking "cancel". However, the Output is not equal to $null...
      I poked around in the script a bit, but i couldn't fix the problem myself.
      Do you know where/why this happens?
      
      Thank you & Greetings
      Matthias
    • PS:
      This is the code:
      
      while ($true) {
              $Creds = (Get-Credential -User $env:USERNAME -Message "Please enter your Username and Password:")
              Write-Host "Validating..."
              if (($null -ne $Creds -and $Creds.GetNetworkCredential().password -match "^[0-9]{4,8}$") -or ($null -eq $Creds)){
                  return $Creds
              }
          }
    • Hello Matthias,
      
      I found the bug in PS2EXE. Quiet easy to correct, but I have to release a new version of PS2EXE. I will do this soon.
      
      Greetings
      
      Markus
      
    • Hello Matthias,
      
      I released the new version 0.5.0.13 of PS2EXE today that returns $NULL correctly when aborting the credential window.
      
      Greetings
      
      Markus
      
    • Hi Markus,
      
      Thank you for your quick response, works great!
51 - 60 of 143 Items