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. Now here:
4.7 Star
36,815 times
Add to favorites
E-mail Twitter Digg Facebook
  • Exit codes
    5 Posts | Last post March 18, 2019
    • It looks like in something has changed with exit codes,Ending a script with Exit 1 no longer fills the $LASTEXITCODE.  
    • This is only on exe files created with -NoConsole
    • Hello jackofalltech,
      this behavior is not PS2EXE specific, it is Windows specific for programs compiled to "WINEXE" (-NoConsole).
      In a cmd.exe you get the Errorlevel of those programs with the following code (for Powershell there are similiar ways):
      start /wait NoConsoleProg.exe
      echo %ERRORLEVEL%
    • I could have swore this was working a few weeks ago 
    • Hello jackofalltech,
      that never worked. Just start "notepad.exe" from a command line (cmd.exe or PowerShell.exe) to see what I mean. You cannot get an exit code from a program that is independently running, you have to (manually) wait for it to exit.
  • Pop Up Error Boxes
    4 Posts | Last post March 08, 2019
    • When running newly created exe, every time there is an error in the background a window pops up showing that error message.  Is there a way to turn that off?
      I have a program that checks for certain thing on a computer. But if it can't ping it all the checks it tries to perform generates these error windows which I don't need to see.
      I'm creating exe using 2.0.ps1\ -inputfile .\file.ps1 -outputfile .\file.exe -noconsole
    • Sorry typo above.   
      I'm creating exe using: ps2exe.ps1 -inputfile .\file.ps1 -outputfile .\file.exe -noconsole
    • That is what the -NoConsole switch will do if you want to hid the error message add -ErrorAction SilentlyContinue or | out-null to the command that is throwing the error 
    • Hello BFrisan,
      this behaviour is by design.
      You have to search for the command that generates the error and fix the error or prevent the error message by using the "-ErrorAction SilentlyContinue" option or by redirecting the error output like this (example is Get-ChildItem  for a not existing file):
      Get-ChildItem NotexistingFile 2> $NULL
  • BrowseForFolder on top
    4 Posts | Last post March 04, 2019
    • Hello Markus,
      I have a form with a button to show a BrowseForFolder object.
      I wanted the BrowseForFolder object to be MostTop, so I did this:
          $handle = [System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle
          $object = New-Object -ComObject Shell.Application
          $folder = $object.BrowseForFolder($handle, $Message, $browseForFolderOptions, $InitialDirectory)
      It's working fine when I run the script, but it's freezing my form without showing the BrowseForFolder object when I run the .exe.
      Could you please tell how I can fix the $handle?
    • This is what I use and it works for me 
      [System.Reflection.Assembly]::LoadWithPartialName("") | Out-Null
      $SourceForm = New-Object System.Windows.Forms.FolderBrowserDialog
      $SourceForm.Rootfolder = "MyComputer"
      $SourceForm.Description = "Browse For Folder"
      IF ($SourceForm.SelectedPath){$Path = $SourceForm.SelectedPath}
    • Hello AG_G1,
      when running your code in a compiled script, there is no window handle because you didn't created one. Please try the following code to use the parent process' window:
      $handle = [System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle
      if ($handle -eq 0) { $handle = (Get-Process -PID ((Get-WMIObject -Class Win32_Process -Filter "ProcessID=$PID").ParentProcessId)).MainWindowHandle }
      $object = New-Object -ComObject Shell.Application
      Another problem that can occur is an issue with MTA and COM (should occur only when using PowerShell V2) that leads to freezing windows. If this is your problem try to compile your script with the additional Parameter -STA
    • Thanks!
      I didn't change my code and add the -STA parameter, and it works fine!
      Thanks again.
  • Over Come 16777214
    5 Posts | Last post March 02, 2019
    • was wondering if you had any idea of how to overcome this error 
      error CS1034: Compiler limit exceeded: Line cannot exceed
      16777214 characters
    • Hello jackofalltech,
      I need more information to answer to this.
      Is your script file that big or a line that long? What encoding are you using? Do you get this error with every script or only with a special one? If only one what is special about it?
    • Sorry about that, this happens if the script that you are converting has more then 16777214 characters in it its an error from the CompileAssemblyFromSource($cp, $progrmFram). basically what Im asking is if you have an idea of how to get around the character limit that the C# compiling process has 
    • Hello hackofalltech,
      I do not think there is a way to get around it.
      You can save the script to a file using the following code of PS2EXE.PS1:
      $content = Get-Content -LiteralPath ($inputFile) -Encoding UTF8 -ErrorAction SilentlyContinue
      $scriptInp = [string]::Join("`r`n", $content)
      $script = [System.Convert]::ToBase64String(([System.Text.Encoding]::UTF8.GetBytes($scriptInp)))
      -> now you have to save $script into a file.
      Second you have to replace the line
      string script = System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(@"$($script)"));
      in PS2EXE.ps1 with a line of code that loads the file saved before into the variable script.
      But I guess that would not really make sense, you had to deliver both files now (executable and file with script).
      I would advice you to think about why your source file is that big (never heard of a script with a size of 16 MB before).
    • thanks, 
      That pretty  much what I have come up with too. 
      I had a issue with converting to BASE64 code and found this workaround but I was unable to apply it PS2EXE 
      basically it converts the bytes on a block basis. 
      the script I am working with has a lot of files stored in BASE64 Code thats why its so large 
  • PS2EXE and Powershell scripts opening Excel files problem...
    6 Posts | Last post February 13, 2019
    • I have a powershell script that opens an Excel file and looks at the first sheet and reads the data from that and loads it into two datagridviews (each datagrid is on a separate tabpage on a tab control) in winforms.
      When I run the .ps1 from Powershell environment, it successfully reads the Excel file and the datagridviews load data successfully from the spreadsheet.
      When I build an .EXE from the same .ps1 and run the .EXE I'm getting weird behavior.. sometimes neither datagridview has data and I get errors that appear to be due to the Excel opening but having no content inside.. resulting in NULL value errors.  Sometimes, only the 1st tab page's datagridview has data and the 2nd one does not.  This is strange because the data is read from the spreadsheet and stored in the same array that is used as the source for both datagridviews.  So if the first datagridview successfully shows data, then there's no reason the 2nd shouldn't.
      I'm not sure why there's this difference in behavior between the .PS1 run from Powershell vs running the .EXE.
      Could someone shed some light on why this may be happening?
    • Hello zathrus1,
      I have no idea why the COM interface behaves unstable with PS2EXE.
      You might try to put some "Start-Sleep 1" commands before every Excel action to find out the critical command(s), my guess is Excel is too busy.
      To help more, I would need some of your code to make Tests.
    • Hi Markus,
      I could send you the code.  Do you have a way I can directly send it rather than post it publicly?
      Also, do you need the excel document?  or do you think just looking at the code may be sufficient?
    • Markus: 
      I should mention specifically that there appears to be a difference of behavior between running my .ps1 in ISE (where the script successfully reads the excel data and loads the 2
      datagridviews I have on 1st or 2nd try.. it is sporadic and varies run by run), and running from command line in a cmd window or using ps2exe and clicking on it to run.  the latter two scenarios exhibit the same behavior.. datagridview #1 loads data fine but #2 is blank.. the strange thing is that both datagridviews draw from the same data obtained from the same Excel spreadsheet worksheet during the same call.  The call parses the data and puts it into an array.  That array is then used by both datagridviews.
      I'll insert some sleep timers in various places to see if I can get the 2nd datagridview to display data.. I've learned a lesson that I should not use ISE for actual testing.. the behavior is different.
    • Hello zathrus1,
      one idea I have is that you're using a 32 bit environment when your script succeeds and a 64 bit environment when it fails. Since Excel is a 32 bit application there might be problems when converting form 64 to 32 bit.
      Can you try to run your script in a 32 bit PowerShell? You can start it with
      You see in what environment you are with
      (the result should be AMD64 or x86)
    • Hi Markus, 
      I wound up going to the part of code where the datagridview wasn't loading the data, apparently because for some reason adding rows to one of the datatables started failing.. so I used a different method which used different variable representing a row, and suddenly everything works again... Thanks for your suggestion about bitness.. it might explain the difference in behavior I observed..  
  • Calling a specific PowerShell function
    7 Posts | Last post February 10, 2019
    • You can use:
      powershell -command "& { . <path>\script1.ps1; My-Func param}"
      To calling a specific PowerShell function from the command line.
      { do somthing }
      Is there a way to do this with PS2EXE-GUI?
    • Hello digisoft1,
      I am not sure that I understand your question right.
      According to your example, I guess you want to do something like that:
      powershell -command "& { . <path>\script1.exe; My-Func param}"
      I'm sorry to say that this won't work. PS2EXE compiles to executables, and there is no way an executable can define a function for the calling shell.
    • I found a solution:
      { do somthing with param}
      { "My-Func" {My-Func($Args[1])}
      I can call the internal function My-Func with param as follows:
      script1.ps1 My-Func variable
    • Correction - I call the EXE.
      I can call the internal function My-Func with param as follows:
      script1.exe My-Func variable
    • Found another error, that is fixed in this version. (removes commas and parenthesis from function call in switch statement)
      { do somthing with param1 and param2}
      { "My-Func" {My-Func $Args[1] $Args[2]}
      I can call the internal function My-Func with params as follows:
      script1.ps1 My-Func variable1 variable2
    • Last try....
      function My-Func($param1,$param2)
      { do somthing with $param1 and $param2}
      { "My-Func" {My-Func $Args[1] $Args[2]}
      I can call the internal function My-Func with params as follows:
      script1.exe My-Func variable1 variable2
    • Hello digisoft1,
      I am pleased that you found a working solution.
  • Long path support?
    6 Posts | Last post February 07, 2019
    • Don't suppose there's any chance of someone updating this for .NET 4.62 or above for long path support?
      I have a few scripts now that work perfectly in console but fail when compiled.
    • Hello Scepticyn,
      I do not know about issues with .Net 4.62. 
      I do not know about issues with long paths. 
      Is there any chance you explain where your troubles are, so I might help you?
    • Hi, thanks
      Long path support (over 260 characters) can be enabled Windows10 and above:
      Powershell also allows this through the '-LiteralPath' parameter on file operations and using unicode path names, for example:
      Get-ChildItem -LiteralPath \\?\servername\this_path_is_over_260characterlongxxxxxx
      Will now work if long paths are enabled on the workstation.
      The above command works in my script if I run it using ISE or console, but if compiled by PS2EXE it fails with a path name error.
      Hope this helps
    • Hello Scepticyn,
      okay, I understand now. What is missing for long paths to work is obviously a manifest:
      I made a test and it failed. I will investigate further.
    • Hello Scepticyn,
      ok, I got it. One needs a special manifest at compile time and a special config file at run time to support long paths (thank you Microsoft for making things easy :-) ).
      I will try to release a new version next week that supports this.
    • Hello Scepticyn,
      I released the new version today that supports long paths with the parameter -longPaths.
      Important: The generated config file has to be present in the same directory as the executable.
  • Import-Module SCCM
    3 Posts | Last post February 07, 2019
    • Hello! 
      Thanks for maintaining this. I've run into a small problem. If I do this:
      Import-Module (Join-Path $(Split-Path $ENV:SMS_ADMIN_UI_PATH) ConfigurationManager.psd1)
      In the script form, it works fine. In the compiled form, it complains about being an old version. Here's the error text:
       ERROR: A new version of the console is available (5.1810.1075.1700). Cmdlets may not function as expected or may corrupt your site's configuration if they are a different version than your 
      I've done a little testing, but I haven't had a chance to dig in and see what might be causing the problem. 
    • Hello Al,
      I will test this next week when I have access to an SCCM Environment.
    • Hello Al,
      I think there is an issue because the System Center Config Manager module is only a 32 bit module and not native 64 bit.
      Please compile your script with the additional parameter -x86 to aim 32 bit coding and the error message should disappear.
  • Arguments possible?
    3 Posts | Last post January 29, 2019
    • Hi, i would like to know if it is possible to pass Parameters with Arguments to the PowerShell Script? 
    • Hello Martin,
      I guess you're asking if a compiled script can receive parameters. Yes, and it works just like the original script, for example:
      compiledscript.exe "Position Parameter" -Name "Named Parameter"
      But you have to be careful, every parameter has the type string and gets converted to the requested type (if possible).
    • It´s working as expected. Thank you Markus for your Work.
      Greetz from Bremen
  • Dot Sourced scripts
    3 Posts | Last post December 29, 2018
    • I didn't find much about "including" other ps scripts.  If the feature exists, I'd like to know how.  If not, this is a feature request.
      I like to separate GUI from functions and such.  The GUI script is dot sourced into the main script.  Usually, the functions are also dot sourced.  Could the compile process follow the dot sourced file(s) recursively?
      As I understand it (probably wrong), dot sourcing is equivalent to copy/paste the file at that location.
    • Hello Bill,
      compiling included scripts is not possible, and I guess it will never be. It would require parsing the script for script including commands, which would be a very faulty process. Then compiling may fail or compile the wrong script because the included script is not present at compile time or the included script or the path to it is changed at runtime. There are some additional problems that may occur.
      Hope you will get along without this feature.
    • I understand.  If anyone else finds this useful, here is a rough outline of a wrapper to accomplish what I need.
      $regex='^\. .*$'
      function expand_dotsrc {
          foreach($line in Get-Content $src) {
              if($line -match $regex){
                  '# inserted dot sourced file ' + $line.Substring(2) | Out-File -Append -FilePath $tempfile
                  expand_dotsrc $line.Substring(2)
                  '# end insert ' + $line.Substring(2)  | Out-File -Append -FilePath $tempfile
              } else {
                  $line  | Out-File -Append -FilePath $tempfile
      expand_dotsrc $source
      #run ps2exe here on $tempfile
81 - 90 of 184 Items