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
(37)
34,259 times
Add to favorites
11/15/2019
E-mail Twitter del.icio.us Digg Facebook
Sign in to ask a question


  • 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?
      
      Greetings
      
      Markus
    • 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).
      
      Greetings
      
      Markus
      
      
    • 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 
      https://mnaoumov.wordpress.com/2013/08/20/efficient-base64-conversion-in-powershell/ 
      
      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.
      
      Greetings
      
      Markus
      
    • 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
      
      C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
      
      You see in what environment you are with
      $ENV:PROCESSOR_ARCHITECTURE
      (the result should be AMD64 or x86)
      
      Greetings
      
      Markus
      
      
    • 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.
      --
      My-Func(param)
      { 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.
      
      Greetings
      
      Markus
    • I found a solution:
      script1.ps1
      ----
      My-Func(param)
      { do somthing with param}
      Switch($Args[0])
      { "My-Func" {My-Func($Args[1])}
      }
      ----
      I can call the internal function My-Func with param as follows:
      script1.ps1 My-Func variable
      
      Flemming
    • 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)
      script1.ps1
      ----
      My-Func(param1,param2)
      { do somthing with param1 and param2}
      Switch($Args[0])
      { "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....
      script1.ps1
      ----
      function My-Func($param1,$param2)
      { do somthing with $param1 and $param2}
      Switch($Args[0])
      { "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.
      
      Greetings
      
      Markus
  • 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?
      
      
      Greetings
      
      Markus
    • Hi, thanks
      
      Long path support (over 260 characters) can be enabled Windows10 and above:
      
      https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
      
      https://www.howtogeek.com/266621/how-to-make-windows-10-accept-file-paths-over-260-characters/
      
      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: https://blogs.msdn.microsoft.com/jeremykuhne/2016/07/30/net-4-6-2-and-long-paths-on-windows-10/
      
      I made a test and it failed. I will investigate further.
       
      Greetings
      
      Markus
    • 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.
      
      Greetings
      
      Markus
    • Hello Scepticyn,
      
      I released the new version 0.5.0.14 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.
      
      Greetings
      
      Markus
  • 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 
      site.
      
      I've done a little testing, but I haven't had a chance to dig in and see what might be causing the problem. 
      
      Thanks!
         -Al
    • Hello Al,
      
      I will test this next week when I have access to an SCCM Environment.
      
      Greetings
      
      Markus
    • 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.
      
      Greetings
      
      Markus
      
  • 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).
      
      Greetings
      
      Markus
       
    • 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.
      
      Thanks,
      Bill
    • 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.
      
      Greetings
      
      Markus
       
    • I understand.  If anyone else finds this useful, here is a rough outline of a wrapper to accomplish what I need.
      
      $source='.\ds2.ps1'
      $tempfile='.\temp.ps1'
      $regex='^\. .*$'
      
      function expand_dotsrc {
          param(
              [string]$src
          )
      
          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
  • Using GUI
    3 Posts | Last post December 21, 2018
    • Hello,
      
      What a nice tool, thanks !
      
      However I created a powershell program with a GUI.
      I wanted to transform it in a exe with your program but I have error messages when I use PS2EXE.
      
      "This Property can't be found in this object" (translated from french), for all this properties :
      
      - Autoscroll
      - AUtosize
      - MinimizeBox
      - MaximizeBox
      - WindowState
      - SizeGripStyle
      - Startposition
      - Fromfile
      - Background
      - Text
      - Size
      
      Is there a way to manage them in your program ?
      
      Thanks a lot.
      
      Regards
      
      
    • Hello R. Ramirez,
      
      can it be you have to put one of the following commands at the start of your script?
      
      If you are implementing a WinForms GUI:
      Add-Type -AssemblyName System.Windows.Forms
      
      If you are implementing a WPF GUI:
      Add-Type -AssemblyName PresentationFramework
      
      Or do the errors occur at compile time?
      
      
      Greetings
      
      Markus
    • Thank you so much Markus, it worked perfectly.
      
      I had one the 1st command in my script but it was not at the top of it.
      
      Now it's done and it works.
      
      Excellent job, thanks again !
  • 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
71 - 80 of 171 Items