|
using Microsoft.CSharp; |
|
using System; |
|
using System.CodeDom.Compiler; |
|
using System.Collections; |
|
using System.Collections.Generic; |
|
using System.Collections.ObjectModel; |
|
using System.Diagnostics; |
|
using System.Globalization; |
|
using System.IO; |
|
using System.IO.Compression; |
|
using System.Linq; |
|
using System.Management; |
|
using System.Management.Automation; |
|
using System.Net; |
|
using System.Reflection; |
|
using System.Runtime.CompilerServices; |
|
using System.Runtime.InteropServices; |
|
using System.Text; |
|
using System.Text.RegularExpressions; |
|
using System.Windows; |
|
using System.Windows.Controls; |
|
using System.Windows.Documents; |
|
using System.Windows.Input; |
|
using System.Windows.Interop; |
|
using System.Windows.Media; |
|
|
|
// Insipred by and credits to Win-PS2EXE by Markus Scholts (https://github.com/MScholtes/PS2EXE/tree/master/Win-PS2EXE) |
|
|
|
namespace ps2exedotnet |
|
{ |
|
public class UserOptions |
|
{ |
|
// input objects |
|
public string inputscript = ""; |
|
public string outputfile = ""; // folder/file |
|
public string iconfile = ""; |
|
public string embedfiles = ""; // dictionary array |
|
|
|
// metadata |
|
public string fileversion = ""; // n.n.n.n |
|
public string title = ""; |
|
public string description = ""; |
|
public string product = ""; |
|
public string company = ""; |
|
public string copyright = ""; |
|
public string trademark = ""; |
|
public string locale = ""; // numeric |
|
|
|
// runtime options |
|
public string platform = ""; |
|
public bool mta; |
|
public bool encrypt; // experimental |
|
public bool nocompress; |
|
public bool basic; |
|
public bool noconsole; |
|
public bool nooutput; |
|
public bool conhost; |
|
public bool noerror; |
|
public bool admin; |
|
public bool unicode; |
|
public bool configfile; |
|
public bool longpaths; |
|
public bool supportos; |
|
public bool credgui; |
|
public bool exitoncancel; |
|
public bool virt; |
|
public bool novisualstyles; |
|
public bool dpi; |
|
public bool winformsdpi; |
|
public bool preparedebug; |
|
public bool raw; // experimental |
|
public bool run; |
|
public bool pshost; // experimental |
|
public bool openfolder; // experimental |
|
public bool core; // experimental |
|
public bool arm; // experimental |
|
public string dotnetplatform = "w"; // experimental |
|
} // UserOptions |
|
//enum paramset {None,All,Gui,Console,User} |
|
|
|
// Interaction logic for MainWindow.xaml |
|
public partial class MainWindow : Window |
|
{ |
|
private static bool disableListEvent = false; // Resolve_Dependency' semaphore for checkboxes |
|
private static bool groupSelection = false; // Resolve_Dependency' semaphore for listbox |
|
//private static string usersettings = Environment.CurrentDirectory + @"\ps2exedotnet.ini"; |
|
|
|
public MainWindow() |
|
{ |
|
InitializeComponent(); |
|
//Set_localeMenu(); |
|
// Set the width of the command buttons evenly across the width of the button bar; experimental |
|
/*Window pWindow = (Window)Find_ParentWindow(); |
|
if (pWindow == null) return; |
|
StackPanel cmdBar = (StackPanel)pWindow.FindName("ButtonBar"); |
|
int i = 0; |
|
foreach (Button btn in cmdBar.Children) { |
|
if (i == 0) { |
|
btn.Margin = new Thickness(0, 0, 0, 0); |
|
} else { |
|
btn.Margin = new Thickness(16, 0, 0, 0); |
|
} |
|
i++; |
|
}*/ |
|
//MessageBox.Show("StackPanel width: "+cmdBar.ActualWidth , "Run", MessageBoxButton.OK, MessageBoxImage.Information); |
|
|
|
} |
|
|
|
//private static void Update_StatusBar(object sender) {} // Update_StatusBar |
|
//???private static void Start_progress() {} // Start_progress |
|
//private static void Set_localeMenu() {} // Set_localeMenu |
|
|
|
private static void Start_CompiledApp() |
|
{ |
|
Window pWindow = (Window)Find_ParentWindow(); |
|
if (pWindow == null) return; |
|
|
|
TextBox userTargetFile = (TextBox)pWindow.FindName("TargetFile"); |
|
string tgt = userTargetFile.Text; |
|
if (tgt != "") tgt = tgt.Trim(); |
|
if (tgt != "") |
|
{ |
|
if (System.IO.Directory.Exists(tgt)) |
|
{ |
|
TextBox userSourceFile = (TextBox)pWindow.FindName("SourceFile"); |
|
string src = userSourceFile.Text; |
|
if (src != "") src = src.Trim(); |
|
if (src == "") |
|
MessageBox.Show("Target file not specified", "Run", MessageBoxButton.OK, MessageBoxImage.Error); |
|
else |
|
{ |
|
string targetexe = System.IO.Path.Combine(tgt, System.IO.Path.GetFileNameWithoutExtension(src)) + ".exe"; |
|
if (System.IO.File.Exists(targetexe)) Process.Start(targetexe); |
|
else MessageBox.Show("Target 'exe' file not found", "Run", MessageBoxButton.OK, MessageBoxImage.Error); |
|
} |
|
} |
|
else |
|
{ |
|
MessageBox.Show("Target 'exe' file not found", "Run", MessageBoxButton.OK, MessageBoxImage.Error); |
|
} |
|
} |
|
else |
|
{ |
|
TextBox userSourceFile = (TextBox)pWindow.FindName("SourceFile"); |
|
string src = userSourceFile.Text; |
|
if (src != "") src = src.Trim(); |
|
if (src == "") |
|
MessageBox.Show("Target file not specified", "Run", MessageBoxButton.OK, MessageBoxImage.Error); |
|
else |
|
{ |
|
string targetexe = System.IO.Path.ChangeExtension(src,"exe"); |
|
if (System.IO.File.Exists(targetexe)) Process.Start(targetexe); |
|
else MessageBox.Show("Target 'exe' file not found", "Run", MessageBoxButton.OK, MessageBoxImage.Error); |
|
} |
|
} |
|
} // Start_CompiledApp |
|
|
|
private void Start_help() |
|
{ |
|
// TODO: prevent multiple help windows open; list subprocesses or check slave windows |
|
HelpWindow helpWindow = new HelpWindow(){Owner = this}; |
|
helpWindow.Show(); |
|
} // Start_help |
|
|
|
// Validate, test, convert |
|
private static bool Confirm_Parameters(ref UserOptions options) { |
|
if (null == options) return false; |
|
|
|
// Test files |
|
if (!string.IsNullOrEmpty(options.inputscript) && !System.IO.File.Exists(options.inputscript)) |
|
{ |
|
MessageBox.Show("The source file not found", "Confirm", MessageBoxButton.OK, MessageBoxImage.Error); |
|
return false; |
|
} |
|
|
|
if (!string.IsNullOrEmpty(options.outputfile) && !System.IO.Directory.Exists(options.outputfile)) |
|
{ // it's a file |
|
if (!Regex.IsMatch(options.outputfile, @"\.exe$")) // test extension |
|
{ |
|
MessageBox.Show("Output file must have '.exe' extension", "Confirm", MessageBoxButton.OK, MessageBoxImage.Error); |
|
return false; |
|
} |
|
|
|
// test parent directory |
|
string parent = System.IO.Path.GetDirectoryName(options.outputfile); |
|
if (!System.IO.Directory.Exists(parent)) |
|
{ |
|
MessageBox.Show("The output directory not found", "Confirm", MessageBoxButton.OK, MessageBoxImage.Error); |
|
return false; |
|
} |
|
} |
|
|
|
if (!string.IsNullOrEmpty(options.inputscript) && |
|
!string.IsNullOrEmpty(options.outputfile) && |
|
options.outputfile == options.inputscript) |
|
{ |
|
MessageBox.Show("Input and output filenames cannot be the same", "Confirm", MessageBoxButton.OK, MessageBoxImage.Error); |
|
return false; |
|
} |
|
|
|
if (!string.IsNullOrEmpty(options.iconfile) && !System.IO.File.Exists(options.iconfile)) |
|
{ |
|
MessageBox.Show("Icon file not found", "Confirm", MessageBoxButton.OK, MessageBoxImage.Error); |
|
return false; |
|
} |
|
|
|
// Test version value; regex looks ugly coz system.version cannot parse a single int |
|
/*if (!string.IsNullOrEmpty(options.fileversion)) |
|
{ |
|
if (Regex.IsMatch(options.fileversion, @"\.\.")) options.fileversion = options.fileversion.Replace("..",".0.").Replace("..",".0."); |
|
if (Regex.IsMatch(options.fileversion, @"\.$")) options.fileversion += "0"; |
|
if (!Regex.IsMatch(options.fileversion, @"\.")) options.fileversion += ".0"; |
|
}*/ |
|
if (!string.IsNullOrEmpty(options.fileversion) && |
|
!Regex.IsMatch(options.fileversion, @"^\d+\.\d+\.\d+\.\d+$|^\d+\.\d+\.\d+$|^\d+\.\d+$|^\d+$")) |
|
{ |
|
MessageBox.Show("Invalid version specified. Valid version format is n.n.n.n, n.n.n, n.n, or n ('n' is numeric val)", "Confirm", MessageBoxButton.OK, MessageBoxImage.Error); |
|
return false; |
|
} |
|
|
|
if (!string.IsNullOrEmpty(options.locale)) |
|
{ |
|
//int x;out int x |
|
if (!int.TryParse(options.locale, out _)) |
|
{ |
|
MessageBox.Show("Parameter 'Locale' must be numeric", "CoConfirmmpile", MessageBoxButton.OK, MessageBoxImage.Error); |
|
return false; |
|
} |
|
} |
|
|
|
return true; |
|
} // Confirm_Parameters |
|
|
|
// Collects all user parameters in struct |
|
private static UserOptions Get_Parameters(bool nocheck=false) |
|
{ |
|
Window pWindow = (Window)Find_ParentWindow(); |
|
if (pWindow == null) return null; |
|
|
|
UserOptions userparam = new UserOptions(); |
|
|
|
TextBox userSourceFile = (TextBox)pWindow.FindName("SourceFile"); |
|
userparam.inputscript = userSourceFile.Text; |
|
if (userparam.inputscript != "") userparam.inputscript = userSourceFile.Text.Trim(); |
|
if (userparam.inputscript == "") |
|
{ |
|
MessageBox.Show("Source file not specified", "Compile", MessageBoxButton.OK, MessageBoxImage.Error); |
|
return null; |
|
} |
|
|
|
TextBox userTargetFile = (TextBox)pWindow.FindName("TargetFile"); |
|
userparam.outputfile = userTargetFile.Text; |
|
if (userparam.outputfile != "") userparam.outputfile = userTargetFile.Text.Trim(); |
|
if (userparam.outputfile == "") userparam.outputfile = System.IO.Path.GetDirectoryName(userparam.inputscript); |
|
if (System.IO.Directory.Exists(userparam.outputfile)) |
|
{ // if directory then append source file name |
|
userparam.outputfile = System.IO.Path.Combine(userparam.outputfile, System.IO.Path.GetFileNameWithoutExtension(userparam.inputscript)) + ".exe"; |
|
} |
|
else if (!System.IO.File.Exists(System.IO.Path.GetDirectoryName(userparam.outputfile))) |
|
MessageBox.Show("Output directory does not exist", "Compile", MessageBoxButton.OK, MessageBoxImage.Error); |
|
|
|
TextBox tb = (TextBox)pWindow.FindName("EmbedFiles"); |
|
if (tb.Text != "") userparam.embedfiles = tb.Text.Trim(); |
|
tb = (TextBox)pWindow.FindName("IconFile"); |
|
if (tb.Text != "") userparam.iconfile = tb.Text.Trim(); |
|
tb = (TextBox)pWindow.FindName("FileVersion"); |
|
if (tb.Text != "") userparam.fileversion = tb.Text.Trim(); |
|
else userparam.fileversion = "0.0.0.0"; |
|
tb = (TextBox)pWindow.FindName("FileDescription"); |
|
if (tb.Text != "") userparam.description = tb.Text.Trim(); |
|
tb = (TextBox)pWindow.FindName("ProductName"); |
|
if (tb.Text != "") userparam.product = tb.Text.Trim(); |
|
tb = (TextBox)pWindow.FindName("Copyright"); |
|
if (tb.Text != "") userparam.copyright = tb.Text.Trim(); |
|
tb = (TextBox)pWindow.FindName("Locale"); |
|
if (tb.Text != "") userparam.locale = tb.Text.Trim(); |
|
|
|
CheckBox cb = (CheckBox)pWindow.FindName("NoConsole"); |
|
userparam.noconsole = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("NoOutput"); |
|
userparam.nooutput = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("NoError"); |
|
userparam.noerror = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("RequireAdmin"); |
|
userparam.admin = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("ConfigFile"); |
|
userparam.configfile = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("MTA"); |
|
userparam.mta = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("ConHost"); |
|
userparam.conhost = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("Unicode"); |
|
userparam.unicode = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("LongPaths"); |
|
userparam.longpaths = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("SupportOS"); |
|
userparam.supportos = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("CredentialGUI"); |
|
userparam.credgui = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("ExitOnCancel"); |
|
userparam.exitoncancel = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("Virtualize"); |
|
userparam.virt = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("NoVisualStyles"); |
|
userparam.novisualstyles = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("DPIAware"); |
|
userparam.dpi = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("WinFormsDPIAware"); |
|
userparam.winformsdpi = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("PrepareDebug"); |
|
userparam.preparedebug = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("NoCompress"); |
|
userparam.nocompress = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("Basic"); |
|
userparam.basic = cb.IsChecked.Value; |
|
cb = (CheckBox)pWindow.FindName("Run"); |
|
userparam.run = cb.IsChecked.Value; |
|
//cb = (CheckBox)pWindow.FindName("PSHost"); // ???? |
|
//userparam.pshost = cb.IsChecked.Value; |
|
//cb = (CheckBox)pWindow.FindName("Encrypt"); // experimental; TBD |
|
//userparam.encrypt = cb.IsChecked.Value; |
|
//cb = (CheckBox)pWindow.FindName("OpenFolder"); // experimental |
|
//userparam.openfolder = cb.IsChecked.Value; |
|
|
|
ComboBox cob = (ComboBox)pWindow.FindName("Platform"); |
|
userparam.platform = ((ComboBoxItem)cob.SelectedItem).Content.ToString(); |
|
|
|
return userparam; |
|
} // Get_Parameters |
|
|
|
private bool Test_ParamState() // experimental |
|
{ |
|
Window pWindow = (Window)Find_ParentWindow(); |
|
if (pWindow == null) return true; |
|
|
|
bool dirty = true; |
|
string[] param = new[] {"SourceFile","TargetFile","EmbedFiles","IconFile","FileVersion","FileDescription","ProductName","Copyright","Locale"}; |
|
foreach (string p in param) |
|
{ |
|
TextBox tb = (TextBox)pWindow.FindName(p); |
|
if (tb.Text != "") dirty = false; |
|
} |
|
|
|
return dirty; |
|
} // Test_ParamState |
|
|
|
// Helper that "climbs up" the parent object chain from a window object until the root window object is reached |
|
private static FrameworkElement Find_ParentWindow(object sender = null) |
|
{ |
|
if (null == sender) return Application.Current.MainWindow; |
|
|
|
FrameworkElement GUIControl = (FrameworkElement)sender; |
|
while ((GUIControl.Parent != null) && (GUIControl.GetType() != typeof(MainWindow))) |
|
{ |
|
GUIControl = (FrameworkElement)GUIControl.Parent; |
|
} |
|
|
|
if (GUIControl.GetType() == typeof(MainWindow)) return GUIControl; |
|
return null; |
|
} // Find_ParentWindow |
|
|
|
private static FrameworkElement Find_Control(string name) |
|
{ |
|
return Application.Current.MainWindow.FindName(name) as FrameworkElement; |
|
} // Find_Control |
|
|
|
private static void Resolve_param(CheckBox param) |
|
{ |
|
disableListEvent = true; // prevent looping |
|
Window pWindow = Application.Current.MainWindow; |
|
CheckBox master = param; |
|
CheckBox dependent; |
|
if (master.Name == "WinFormsDPIAware" && master.IsChecked == true) |
|
{ |
|
dependent = pWindow.FindName("SupportOS") as CheckBox; |
|
if (dependent.IsChecked == false) dependent.IsChecked = true; |
|
} |
|
else if (master.Name == "ConfigFile" && master.IsChecked == false) |
|
{ |
|
dependent = (CheckBox)pWindow.FindName("WinFormsDPIAware"); |
|
if (dependent.IsChecked == true) master.IsChecked = true; |
|
} |
|
else if (master.Name == "ConfigFile" && master.IsChecked == false) |
|
{ |
|
dependent = (CheckBox)pWindow.FindName("LongPaths"); |
|
if (dependent.IsChecked == true) master.IsChecked = true; |
|
} |
|
else if (master.Name == "Basic" && master.IsChecked == true) |
|
{ |
|
dependent = (CheckBox)pWindow.FindName("NoCompress"); |
|
if (dependent.IsChecked == true) master.IsChecked = false; |
|
} |
|
else if (master.Name == "NoCompress") |
|
{ // mutual exclusion |
|
dependent = (CheckBox)pWindow.FindName("Basic"); |
|
if (master.IsChecked == true) |
|
{ |
|
if (dependent.IsChecked == true) dependent.IsChecked = false; |
|
} |
|
else |
|
{ |
|
dependent.IsChecked = false; // resets prev state anyway |
|
} |
|
} |
|
else if (master.Name == "MTA" && master.IsChecked == true) |
|
{ // possible mutual exclusion |
|
dependent = (CheckBox)pWindow.FindName("NoConsole"); |
|
if (dependent.IsChecked == true) dependent.IsChecked = false; |
|
} |
|
else if (master.Name == "NoConsole" && master.IsChecked == true) |
|
{ |
|
dependent = (CheckBox)pWindow.FindName("MTA"); |
|
if (dependent.IsChecked == true) dependent.IsChecked = false; |
|
dependent = (CheckBox)pWindow.FindName("ConHost"); |
|
if (dependent.IsChecked == true) master.IsChecked = false; |
|
} |
|
// Incompatibilities, mutual exclusions |
|
else if (master.Name == "ConHost" && master.IsChecked == true) |
|
{ |
|
dependent = (CheckBox)pWindow.FindName("NoConsole"); |
|
if (dependent.IsChecked == true) master.IsChecked = false; |
|
} |
|
disableListEvent = false; |
|
} // Resolve_param |
|
|
|
#region EVENT HANDLERS |
|
// Parameter set selector handler |
|
private void Parameter_Select(object sender, SelectionChangedEventArgs e) |
|
{ |
|
e.Handled = true; // ??? |
|
if (!Regex.IsMatch(Parameters.SelectedValue.ToString(), @":")) return; |
|
Window pWindow = Application.Current.MainWindow; |
|
|
|
ComboBoxItem cbi = (sender as ComboBox).SelectedItem as ComboBoxItem; |
|
string mode = cbi.Content.ToString(); |
|
if (mode == "<User>") |
|
{ // abit overkill |
|
List<string> selection = new List<string>(); |
|
foreach (CheckBox lbi in listParamSet.Items) { |
|
if (lbi.IsChecked == true) selection.Add(lbi.Name); |
|
} |
|
if (0 == selection.Count) Parameters.SelectedIndex = 0; |
|
else if (3 == selection.Count) Parameters.SelectedIndex = Regex.IsMatch(string.Join(" ", selection), @"(?=.*NoConsole)(?=.*NoError)(?=.*NoOutput)",RegexOptions.IgnoreCase) ? 3 : Parameters.Items.Count - 1; |
|
return; // do nothing |
|
} |
|
groupSelection = true; |
|
int selected = 0; // previous selection state |
|
foreach (CheckBox lbi in listParamSet.Items) { |
|
if (lbi.IsChecked == true) selected++; |
|
if (mode == "None") |
|
{ |
|
if (lbi.IsChecked == true) lbi.IsChecked = false; |
|
if (lbi.IsEnabled == false) lbi.IsEnabled = true; |
|
} |
|
else if (mode == "All") |
|
{ |
|
if (lbi.IsChecked == false) lbi.IsChecked = true; |
|
Resolve_param(lbi); |
|
} |
|
else if (mode == "Inverse") |
|
{ |
|
lbi.IsChecked = !lbi.IsChecked; |
|
Resolve_param(lbi); |
|
} |
|
else if (mode == "GUI App") |
|
{ |
|
if (lbi.Name == "NoConsole") |
|
{ |
|
CheckBox cb = (CheckBox)pWindow.FindName("ConHost"); |
|
if (cb.IsChecked == true) cb.IsChecked = false; |
|
lbi.IsChecked = true; |
|
} |
|
else if (Regex.IsMatch(lbi.Name,"^NoOutput|^NoError")) lbi.IsChecked = true; |
|
else if (lbi.IsChecked == true) lbi.IsChecked = false; |
|
if (lbi.IsEnabled == false) lbi.IsEnabled = true; |
|
} |
|
} // foreach |
|
// synchronize controls |
|
if (mode == "Inverse") |
|
{ |
|
if (selected == listParamSet.Items.Count) |
|
{ |
|
Parameters.SelectedIndex = 0; // none |
|
} |
|
else if (selected == 0) |
|
{ |
|
Parameters.SelectedIndex = 1; // all |
|
} |
|
else Parameters.SelectedIndex = Parameters.Items.Count - 1; // user |
|
} |
|
else if (mode == "GUI App") // uncheck leftovers |
|
{ |
|
if (selected != 0) |
|
{ |
|
CheckBox cb = (CheckBox)pWindow.FindName("ConfigFile"); |
|
cb.IsChecked = false; |
|
} |
|
} |
|
listParamSet.UnselectAll(); |
|
groupSelection = false; |
|
} // Parameter_Select |
|
|
|
// Parameter checkbox preview handler |
|
private void Resolve_Dependency(object sender, MouseButtonEventArgs e) |
|
{ |
|
// NOTE/PROBLEM: too confusing logics; not complete yet |
|
// CAUTION: make sure there is no looping |
|
|
|
if (e.Source.GetType().Name != "CheckBox") return; |
|
//Window pWindow = (Window)Find_ParentWindow(); |
|
//if (pWindow == null) return; |
|
Window pWindow = Application.Current.MainWindow; |
|
|
|
List<string> msg = new List<string>(); |
|
CheckBox master = (CheckBox)e.Source; |
|
CheckBox dependent; |
|
if (master.Name == "WinFormsDPIAware" && master.IsChecked == true) |
|
{ |
|
dependent = pWindow.FindName("SupportOS") as CheckBox; |
|
if (dependent.IsChecked == false) dependent.IsChecked = true; |
|
} |
|
else if (master.Name == "ConfigFile" && master.IsChecked != false) |
|
{ |
|
dependent = (CheckBox)pWindow.FindName("WinFormsDPIAware"); |
|
if (dependent.IsChecked == true) e.Handled = true; |
|
} |
|
else if (master.Name == "ConfigFile" && master.IsChecked != false) |
|
{ |
|
dependent = (CheckBox)pWindow.FindName("LongPaths"); |
|
if (dependent.IsChecked == true) e.Handled = true; |
|
} |
|
else if (master.Name == "MTA" && master.IsChecked == true) |
|
{ // possible mutual exclusion |
|
dependent = (CheckBox)pWindow.FindName("NoConsole"); |
|
if (dependent.IsChecked == true) dependent.IsChecked = false; |
|
} |
|
else if (master.Name == "NoConsole" && master.IsChecked != true) |
|
{ |
|
dependent = (CheckBox)pWindow.FindName("MTA"); |
|
if (dependent.IsChecked == true) dependent.IsChecked = false; |
|
dependent = (CheckBox)pWindow.FindName("ConHost"); |
|
if (dependent.IsChecked == true) |
|
{ |
|
e.Handled = true; |
|
msg.Add("'noConsole' cannot be used with 'conHost'"); |
|
} |
|
} |
|
// Incompatibilities, mutual exclusions |
|
else if (master.Name == "ConHost" && master.IsChecked != true) |
|
{ |
|
dependent = (CheckBox)pWindow.FindName("NoConsole"); |
|
if (dependent.IsChecked == true) |
|
{ |
|
e.Handled = true; |
|
msg.Add("'noConsole' cannot be used with 'conHost'"); |
|
} |
|
} |
|
else if (master.Name == "NoCompress" && master.IsChecked != true) |
|
{ // mutual exclusion |
|
dependent = (CheckBox)pWindow.FindName("Basic"); |
|
if (dependent.IsChecked == true) dependent.IsChecked = false; |
|
} |
|
else if (master.Name == "Basic" && master.IsChecked != true) |
|
{ // mutual exclusion |
|
dependent = (CheckBox)pWindow.FindName("NoCompress"); |
|
if (dependent.IsChecked == true) |
|
{ |
|
e.Handled = true; |
|
msg.Add("'Basic' cannot be used with 'NoCompress'\nDeactivate 'NoCompress' first"); |
|
} |
|
} |
|
// WHAT IS IT????? |
|
/*else if (master.Name == " " && master.IsChecked != true) |
|
{ // possible looping |
|
dependent = (CheckBox)pWindow.FindName("LongPaths"); |
|
if (dependent.IsChecked == true) |
|
{ |
|
e.Handled = true; |
|
} |
|
dependent = (CheckBox)pWindow.FindName("SupportOS"); |
|
if (dependent.IsChecked == true) |
|
{ |
|
e.Handled = true; |
|
} |
|
dependent = (CheckBox)pWindow.FindName("RequireAdmin"); |
|
if (dependent.IsChecked == true) |
|
{ |
|
e.Handled = true; |
|
} |
|
}*/ |
|
|
|
if (msg.Count > 0 && !groupSelection) |
|
MessageBox.Show("Multiple conflicts found:\r\n" + string.Join("\r\n", msg), "Resolve dependency", MessageBoxButton.OK, MessageBoxImage.Error); |
|
} // Resolve_Dependency |
|
|
|
// Parameter checkbox handler |
|
private void List_Check(object sender, RoutedEventArgs e) |
|
{ |
|
if (disableListEvent) return; |
|
|
|
// synchronize controls |
|
List<string> selected = new List<string>(); |
|
foreach (CheckBox lbi in listParamSet.Items) { |
|
if (lbi.IsChecked == true) selected.Add(lbi.Name); |
|
} |
|
if (selected.Count == 0) Parameters.SelectedIndex = 0; // none |
|
else if (selected.Count == listParamSet.Items.Count) Parameters.SelectedIndex = 1; // all |
|
else if (selected.Count == 3) |
|
Parameters.SelectedIndex = Regex.IsMatch(string.Join(" ",selected), @"(?=.*NoConsole)(?=.*NoError)(?=.*NoOutput)",RegexOptions.IgnoreCase) ? 3 : Parameters.Items.Count - 1; |
|
else Parameters.SelectedIndex = Parameters.Items.Count - 1; // user |
|
} // List_Check |
|
|
|
// Command button click |
|
public void Button_Click(object sender, RoutedEventArgs e) |
|
{ |
|
// event is handled afterwards |
|
e.Handled = true; |
|
|
|
// retrieve window parent object |
|
Window pWindow = (Window)Find_ParentWindow(sender); |
|
if (pWindow == null) return; // is this possible? |
|
|
|
if (((Button)sender).Name == "AppClose") |
|
{ // button "Close" -> close application |
|
if (Test_ParamState() || MessageBox.Show("There are changed fields.\r\nAre you sure you want to exit?", "Close", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) |
|
pWindow.Close(); |
|
} |
|
else if (((Button)sender).Name == "CmdRun") Start_CompiledApp(); |
|
else if (((Button)sender).Name == "AppHelp") Start_help(); // experimental |
|
else if (((Button)sender).Name == "HelpClose") {} |
|
//else if (((Button)sender).Name == "AddParam") {} // TODO; experimental |
|
else |
|
{ // button "Compile" -> call Ps2Exe |
|
UserOptions uo = Get_Parameters(); |
|
if (Confirm_Parameters(ref uo)) Ps2Exe.Ps2Exe.Invoke_Ps2Exe(uo); |
|
} |
|
} // Button_Click |
|
|
|
// Click on file picker button ("...") |
|
private void FilePicker_Click(object sender, RoutedEventArgs e) |
|
{ |
|
// retrieve window parent object |
|
Window pWindow = (Window)Find_ParentWindow(null); |
|
if (pWindow == null) return; |
|
|
|
if (((Button)sender).Name != "TargetFilePicker") |
|
{ |
|
// create OpenFileDialog control |
|
Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog |
|
{ |
|
Title = "Select File" |
|
}; |
|
|
|
// set file extension filters |
|
if (((Button)sender).Name == "SourceFilePicker") |
|
{ // button to TextBox "SourceFile" |
|
dialog.DefaultExt = ".ps1"; |
|
dialog.Filter = "PS1 Files (*.ps1)|*.ps1|All Files (*.*)|*.*"; |
|
if (SourceFile.Text != "" && System.IO.Directory.Exists(SourceFile.Text)) |
|
dialog.InitialDirectory = SourceFile.Text; |
|
} |
|
else if (((Button)sender).Name == "EmbedFilePicker") dialog.Filter = "All Files (*.*)|*.*"; |
|
else |
|
{ // button to TextBox "IconFile" |
|
dialog.DefaultExt = ".ico"; |
|
dialog.Filter = "Icon Files (*.ico)|*.ico|All Files (*.*)|*.*"; |
|
if (TargetFile.Text != "" && System.IO.Directory.Exists(TargetFile.Text)) |
|
dialog.InitialDirectory = TargetFile.Text; |
|
} |
|
|
|
// display file picker dialog |
|
Nullable<bool> result = dialog.ShowDialog(); |
|
|
|
// file selected? |
|
if (result.HasValue && result.Value) |
|
{ // fill Texbox with file name |
|
if (((Button)sender).Name == "SourceFilePicker") |
|
{ // button to TextBox "SourceFile" |
|
TextBox userSourceFile = (TextBox)pWindow.FindName("SourceFile"); |
|
userSourceFile.Text = dialog.FileName; |
|
} |
|
else if (((Button)sender).Name == "EmbedFilePicker") |
|
{ // TODO |
|
TextBox embedFile = (TextBox)pWindow.FindName("EmbedFiles"); |
|
string tmpd = System.IO.Path.GetTempPath() + System.IO.Path.GetFileName(dialog.FileName); |
|
string fn = string.Format("\"{0}\"=\"{1}\"",tmpd,dialog.FileName); |
|
if (embedFile.Text == "") embedFile.Text = fn; |
|
else embedFile.Text = string.Join(";",embedFile.Text,fn); |
|
} |
|
else |
|
{ // button to TextBox "IconFile" |
|
TextBox userIconFile = (TextBox)pWindow.FindName("IconFile"); |
|
userIconFile.Text = dialog.FileName; |
|
} |
|
} |
|
} |
|
else |
|
{ // use custom dialog for folder selection because there is no WPF folder dialog!!! |
|
TextBox userTargetFile = (TextBox)pWindow.FindName("TargetFile"); |
|
|
|
// create OpenFolderDialog control |
|
OpenFolderDialog.OpenFolderDialog dialog = new OpenFolderDialog.OpenFolderDialog(); |
|
if (userTargetFile.Text != "") |
|
{ // set starting directory for folder picker |
|
if (System.IO.Directory.Exists(userTargetFile.Text)) |
|
dialog.InitialFolder = userTargetFile.Text; |
|
else |
|
dialog.InitialFolder = System.IO.Path.GetDirectoryName(userTargetFile.Text); |
|
} |
|
else |
|
{ // set starting directory to Documents |
|
TextBox userSourceFile = (TextBox)pWindow.FindName("SourceFile"); |
|
if (userSourceFile.Text != "" && System.IO.File.Exists(userTargetFile.Text)) |
|
{ |
|
dialog.InitialFolder = System.IO.Path.GetDirectoryName(userSourceFile.Text); |
|
|
|
} |
|
else |
|
dialog.InitialFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal); |
|
} |
|
|
|
// display folder picker dialog |
|
System.Windows.Interop.WindowInteropHelper windowHwnd = new System.Windows.Interop.WindowInteropHelper(this); |
|
Nullable<bool> result = dialog.ShowDialog(windowHwnd.Handle); |
|
|
|
if (result.HasValue && result == true) |
|
{ // get result only if a folder was selected |
|
userTargetFile.Text = dialog.Folder; |
|
} |
|
} |
|
} // FilePicker_Click |
|
|
|
// "empty" drag handler |
|
private void TextBox_PreviewDragOver(object sender, DragEventArgs e) |
|
{ |
|
e.Effects = DragDropEffects.All; |
|
e.Handled = true; |
|
} |
|
|
|
// Drop handler: insert filename to textbox |
|
private void TextBox_PreviewDrop(object sender, DragEventArgs e) |
|
{ |
|
object userText = e.Data.GetData(DataFormats.FileDrop); |
|
TextBox tb = sender as TextBox; |
|
if (tb != null && userText != null) |
|
{ |
|
//tb.Text = string.Format("{0}",((string[])userText)[0]); |
|
tb.Text = ((string[])userText)[0]; |
|
} |
|
} // FilePicker_Click |
|
|
|
// Remove focus/selection/content from a control; experimental |
|
private void Window_KeyDown(object sender, KeyEventArgs e) |
|
{ |
|
Window pWindow = Application.Current.MainWindow; |
|
if (e.Key == Key.Escape) |
|
{ |
|
e.Handled = true; |
|
ListBox lparam = (ListBox)pWindow.FindName("listParamSet"); |
|
if (lparam.IsMouseOver) lparam.UnselectAll(); |
|
if (e.Source.GetType().Name == "TextBox") |
|
{ |
|
TextBox tb = e.Source as TextBox; |
|
if (tb.IsMouseOver && !string.IsNullOrEmpty(tb.Text)) tb.Clear(); |
|
} |
|
//FrameworkElement GUIControl = (FrameworkElement)sender; //Find_Children |
|
//GUIControl.LogicalChildren |
|
FocusManager.SetFocusedElement(this, this); |
|
} |
|
//else if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.S) |
|
// Export_UserSettings(); |
|
} // Window_KeyDown |
|
|
|
// Remove focus when clicking outside of a textbox |
|
private void Window_MouseDown(object sender, MouseButtonEventArgs e) |
|
{ |
|
FocusManager.SetFocusedElement(this, this); |
|
} |
|
/*private void Textbox_clear(object sender, MouseButtonEventArgs e) |
|
{ |
|
var focusedElement = FocusManager.GetFocusedElement(this); |
|
if (focusedElement is TextBox tbox && !string.IsNullOrEmpty(tbox.Text)) tbox.Text = ""; |
|
}*/ |
|
#endregion EVENT HANDLERS |
|
} // MainWindow |
|
} // ps2exedotnet |
|
|
|
namespace Ps2Exe |
|
{ |
|
public class Ps2Exe |
|
{ |
|
public static void Invoke_Ps2Exe(ps2exedotnet.UserOptions parameters) |
|
{ |
|
if (null == parameters) return; |
|
if (!Test_parameters(parameters)) return; |
|
|
|
// Generate compiler options -- https://learn.microsoft.com/en-us/dotnet/api/system.codedom.compiler.compilerparameters?view=windowsdesktop-10.0 |
|
string[] alist = Add_assembly(parameters); |
|
CompilerParameters compilerparam = new CompilerParameters(alist, parameters.outputfile) |
|
{ |
|
GenerateInMemory = false, |
|
GenerateExecutable = true |
|
}; |
|
|
|
// Compiler command line parameters |
|
string platform = parameters.platform; |
|
string target = "exe"; |
|
if (parameters.noconsole || parameters.conhost) target = "winexe"; |
|
string manifestParam = null; |
|
if (parameters.admin || parameters.dpi || parameters.supportos || parameters.longpaths) { |
|
manifestParam = string.Format("/win32manifest:{0}.win32manifest", parameters.outputfile); |
|
Export_manifest(parameters, "win32"); |
|
} |
|
if (parameters.virt) { |
|
platform = "x86"; |
|
manifestParam = "/nowin32manifest"; |
|
} |
|
string iconFileParam = null; |
|
if (parameters.iconfile != "") iconFileParam = string.Concat("/win32icon:",parameters.iconfile); |
|
string optimizeParam = null; |
|
if (!parameters.preparedebug) optimizeParam = "/optimize+"; |
|
compilerparam.CompilerOptions = string.Format("/platform:{0} /target:{1} {2} {3} {4}",platform,target,optimizeParam,iconFileParam,manifestParam).TrimEnd(); |
|
|
|
// Debug settings |
|
compilerparam.IncludeDebugInformation = parameters.preparedebug; |
|
if (parameters.preparedebug) compilerparam.TempFiles.KeepFiles = true; |
|
|
|
// Create compiler |
|
// generic dictionary type needed for CSharpCodeProvider |
|
Dictionary<string,string> dict = Activator.CreateInstance<Dictionary<string,string>>(); |
|
//////Dictionary<string, string> dict = new Dictionary<string, string>(); |
|
dict["CompilerVersion"] = "v4.0"; |
|
CSharpCodeProvider csprov = new Microsoft.CSharp.CSharpCodeProvider(dict); |
|
|
|
string csframe = Get_MainProgramSource(parameters, ref compilerparam); |
|
if (csframe.Length < 5) return; |
|
/*if (parameters.pshost) { // experimental |
|
string fn1 = System.IO.Path.ChangeExtension(parameters.outputfile, "cs"); |
|
System.IO.File.WriteAllLines(fn, new[] { csframe }, Encoding.UTF8); |
|
MessageBox.Show("PS host exported", "Compile", MessageBoxButton.OK, MessageBoxImage.Information); |
|
return; |
|
}*/ |
|
CompilerResults cresult = csprov.CompileAssemblyFromSource(compilerparam, csframe); |
|
if (cresult.Errors.Count > 0) |
|
{ |
|
MessageBox.Show("Compile failed", "Compile", MessageBoxButton.OK, MessageBoxImage.Error); |
|
if (System.IO.File.Exists(parameters.outputfile)) |
|
try {System.IO.File.Delete(parameters.outputfile);} catch {} |
|
} |
|
else |
|
{ |
|
if (System.IO.File.Exists(parameters.outputfile)) { |
|
MessageBox.Show("Compile is successful", "Compile", MessageBoxButton.OK, MessageBoxImage.Information); |
|
if (parameters.configfile) Export_manifest(parameters, "exe3"); |
|
if (parameters.run) |
|
{ |
|
if ((DateTime.Now - System.IO.File.GetLastWriteTime(parameters.outputfile)).TotalSeconds < 15) // just in case of compilation false positive |
|
Process.Start(parameters.outputfile); |
|
else |
|
MessageBox.Show("The output file is likely old.\r\nRun compile again or click Run button", "Compile", MessageBoxButton.OK, MessageBoxImage.Warning); |
|
} |
|
} |
|
else if (parameters.run) MessageBox.Show("Output file not found", "Run", MessageBoxButton.OK, MessageBoxImage.Error); |
|
else MessageBox.Show("Output file not found", "Compile", MessageBoxButton.OK, MessageBoxImage.Error); |
|
} |
|
/*if (parameters.openfolder) |
|
{ |
|
System.Diagnostics.Process.Start(@"c:\windows\explorer.exe", System.IO.Path.GetDirectoryName(parameters.outputfile)); |
|
//var psi = new ProcessStartInfo(); |
|
//psi.FileName = @"c:\windows\explorer.exe"; |
|
//psi.Arguments = folder; |
|
//Process.Start(psi); |
|
}*/ |
|
|
|
//try {System.IO.File.Delete(tempinputFile);} catch {} |
|
if (parameters.preparedebug) |
|
{ |
|
string fn = System.IO.Path.ChangeExtension(parameters.outputfile, "cs"); |
|
System.IO.File.WriteAllLines(fn, new[] { csframe }, Encoding.UTF8); |
|
|
|
// NOTE: minified input script is exported in Get_sourcecontent |
|
|
|
string dstSrc = parameters.raw ? Environment.CurrentDirectory : System.IO.Path.GetDirectoryName(parameters.outputfile); |
|
IEnumerator tempfiles = cresult.TempFiles.GetEnumerator(); |
|
while (tempfiles.MoveNext()) |
|
{ |
|
string file = (string)tempfiles.Current; |
|
if (Regex.IsMatch(file, @"\.cs$")) |
|
{ |
|
System.IO.File.Copy(file, dstSrc); |
|
System.IO.File.Delete(file); |
|
} |
|
} |
|
} |
|
|
|
if (parameters.admin || parameters.dpi || parameters.supportos || parameters.longpaths) |
|
{ |
|
string fn = string.Concat(parameters.outputfile,".win32manifest"); |
|
if (System.IO.File.Exists(fn)) System.IO.File.Delete(fn); |
|
} |
|
} // Invoke_Ps2Exe |
|
|
|
// partially duplicates Resolve_Dependency; fallback for the case of inability to resolve parameter conflicts |
|
private static bool Test_parameters(ps2exedotnet.UserOptions options) |
|
{ |
|
List<string> msg = new List<string>(); |
|
if (options.conhost && options.noconsole) |
|
{ |
|
msg.Add("'noConsole' cannot be used with 'conHost'"); |
|
} |
|
if (options.virt) |
|
{ |
|
if (options.longpaths) |
|
msg.Add("'longPaths' cannot be used with 'virtualize'"); |
|
if (options.supportos) |
|
msg.Add("'supportOS' cannot be used with 'virtualize'"); |
|
if (options.admin) |
|
msg.Add("'requireAdmin' cannot be used with 'virtualize'"); |
|
} |
|
if (msg.Count > 0) |
|
{ |
|
MessageBox.Show("Multiple conflicts found:\r\n" + string.Join("\r\n", msg), "Test Parameters", MessageBoxButton.OK, MessageBoxImage.Error); |
|
return false; |
|
} |
|
return true; |
|
} // Test_parameters |
|
|
|
private static string Compress_PSscriptblock(string scriptstring, bool basic=false) |
|
{ |
|
if (scriptstring == "") return ""; |
|
|
|
//System.Collections.ObjectModel. |
|
Collection<System.Management.Automation.PSParseError> psperrors = null; |
|
Collection<PSToken> tokens = System.Management.Automation.PSParser.Tokenize(scriptstring, out psperrors); //.Where(t => t.Type != PSTokenType.Comment || Regex.IsMatch(t.Content, @"^#Requires",RegexOptions.IgnoreCase)); |
|
if (null == tokens || tokens.Count == 0) return scriptstring; |
|
|
|
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.pstoken.type?view=powershellsdk-7.4.0#system-management-automation-pstoken-type |
|
// Parse options |
|
int currentColumn = 1; // script line cursor |
|
bool newLine = false; // sequential newlines semaphore |
|
PSToken prevToken = null; // token cursor to look back |
|
int tindex = 0; // token index to lookup ahead |
|
int t1; // next token index |
|
bool next; |
|
|
|
Regex rxnewl = new Regex(@"^NewLine|^LineContin", RegexOptions.Compiled | RegexOptions.IgnoreCase); |
|
Regex rxhere = new Regex("^@['\"]", RegexOptions.Compiled); |
|
Regex rxoper = new Regex(@"[,+=|/\$\-]", RegexOptions.Compiled); |
|
Regex rxgroup = new Regex(@"Group[SE]", RegexOptions.Compiled | RegexOptions.IgnoreCase); |
|
Regex rxtype = new Regex(@"GroupStart|NewLine|LineContin|Statement", RegexOptions.Compiled | RegexOptions.IgnoreCase); |
|
Regex funckey = new Regex("^funct", RegexOptions.Compiled | RegexOptions.IgnoreCase); |
|
|
|
StringBuilder sb = new StringBuilder(); |
|
foreach (PSToken currentToken in tokens) |
|
{ |
|
// Filter comments except #Requires instruction |
|
if (currentToken.Type == PSTokenType.Comment && !Regex.IsMatch(currentToken.Content, @"^#Requires", RegexOptions.IgnoreCase)) {tindex++; continue;} |
|
|
|
if (rxnewl.IsMatch(currentToken.Type.ToString())) { |
|
currentColumn = 1; |
|
// Handle newlines. Sequential newlines are ignored in order to save space |
|
if (!newLine) |
|
{ |
|
if (basic) sb.Append(Environment.NewLine); |
|
else { |
|
t1 = tindex + 1; |
|
next = t1 < tokens.Count; |
|
// TODO: 1) ignore newline on condition; 2) insert StatementSeparator (;) |
|
if (prevToken != null && rxtype.IsMatch(prevToken.Type.ToString())) {} |
|
else if (next && tokens[t1].Type == PSTokenType.GroupEnd) {} //13=GroupEnd |
|
else if (next && funckey.IsMatch(tokens[t1].Content)) {} |
|
else if (prevToken.Type == PSTokenType.StatementSeparator) {} |
|
else if (prevToken.Content == ")" && next && tokens[t1].Content == "{") {} |
|
//else if (next && tokens[t1].Type == PSTokenType.Variable && !rxgroup.IsMatch(prevToken.Type.ToString())) sb.Append(';'); |
|
//?else if (prevToken.Type == PSTokenType.GroupEnd && currentToken.Type != PSTokenType.Keyword) sb.Append(';'); |
|
else if (prevToken.Type == PSTokenType.Command) sb.Append(';'); |
|
else if (prevToken.Type == PSTokenType.CommandParameter) sb.Append(' '); |
|
else sb.Append(Environment.NewLine); |
|
} |
|
} |
|
newLine = true; |
|
} |
|
else { |
|
newLine = false; |
|
|
|
// Handle any indenting |
|
if (currentColumn < currentToken.StartColumn) |
|
{ |
|
// Handle spaces in between tokens on the same line |
|
// TODO: ignore extra spaces on condition |
|
if (currentColumn != 1) |
|
{ |
|
if (basic) sb.Append(' '); |
|
else { |
|
if (currentToken.Type == PSTokenType.Operator && rxoper.IsMatch(currentToken.Content)) {} //11=Operator |
|
else if (prevToken.Type == PSTokenType.Operator && rxoper.IsMatch(prevToken.Content)) {} |
|
else if (rxgroup.IsMatch(currentToken.Type.ToString()) || prevToken.Type == PSTokenType.StatementSeparator) {} //16=StatementSeparator |
|
else if (currentToken.Type == PSTokenType.Keyword && currentToken.Content != "in") {} //14=keyword |
|
else sb.Append(' '); |
|
} |
|
} |
|
} |
|
|
|
string tokenBody = scriptstring.Substring(currentToken.Start,currentToken.Length); |
|
bool herestring = currentToken.Type == PSTokenType.String && rxhere.IsMatch(tokenBody); |
|
// Handle multi-line strings 5=String |
|
if (!herestring && currentToken.Type == PSTokenType.String && currentToken.EndLine > currentToken.StartLine) { |
|
sb.Append(tokenBody.Replace(Environment.NewLine,"")); |
|
} |
|
else { // Write out a regular token |
|
sb.Append(tokenBody); |
|
} |
|
|
|
// Update current position in the column |
|
currentColumn = currentToken.EndColumn; |
|
} // token type |
|
prevToken = currentToken; |
|
tindex++; |
|
} // token iterator |
|
|
|
return sb.ToString(); |
|
} // Compress_PSscriptblock |
|
|
|
public static string Compress_text(string InputString) |
|
{ |
|
if (string.IsNullOrEmpty(InputString)) return null; |
|
string result; |
|
|
|
using (var uncompressedStream = new MemoryStream(Encoding.UTF8.GetBytes(InputString))) |
|
{ |
|
using (var compressedStream = new MemoryStream()) |
|
{ |
|
// Setting the leaveOpen parameter to true to ensure that compressedStream will not be closed when compressorStream is disposed |
|
// This allows compressorStream to close and flush its buffers to compressedStream and guarantees that compressedStream.ToArray() can be called afterward |
|
// Although MSDN documentation states that ToArray() can be called on a closed MemoryStream, we don't want to rely on that very odd behavior should it ever change |
|
using (var compressorStream = new DeflateStream(compressedStream, CompressionLevel.Optimal, true)) |
|
{ |
|
uncompressedStream.CopyTo(compressorStream); |
|
} |
|
result = Convert.ToBase64String(compressedStream.ToArray()); |
|
} // compressedStream |
|
} // uncompressedStream |
|
|
|
return result; |
|
} // Compress_text |
|
|
|
public static string Expand_text(string InputString) |
|
{ |
|
if (string.IsNullOrEmpty(InputString)) return null; |
|
string result; |
|
|
|
var compressedStream = new MemoryStream(Convert.FromBase64String(InputString)); |
|
using (var decompressorStream = new DeflateStream(compressedStream, CompressionMode.Decompress)) |
|
{ |
|
using (var decompressedStream = new MemoryStream()) |
|
{ |
|
decompressorStream.CopyTo(decompressedStream); |
|
result = Encoding.UTF8.GetString(decompressedStream.ToArray()); |
|
} |
|
} |
|
|
|
return result; |
|
} // Expand_text |
|
|
|
private static string Create_embedFileSection(ps2exedotnet.UserOptions options, ref CompilerParameters cp) |
|
{ |
|
if (options.embedfiles == "") return ""; |
|
|
|
StringBuilder sb = new StringBuilder(); |
|
int i = 0; |
|
sb.Append("string tgtFile = string.Empty, tgtDir = string.Empty;" + Environment.NewLine); |
|
// TODO: compress/expand embed files |
|
List<string> errfile = new List<string>(); |
|
foreach (string el in options.embedfiles.Split(';')) |
|
{ |
|
string[] files = el.Split('='); |
|
string src = files[0].Trim(); // key |
|
string tgt = files[1].Trim(); // value |
|
if (src == "" || tgt == "") continue; |
|
//cp.EmbeddedResources.Add(tgt); |
|
string content = Compress_text(System.IO.File.ReadAllText(tgt)); |
|
if (string.IsNullOrEmpty(content)) {errfile.Add(tgt);continue;} |
|
sb.Append(string.Format("tgtFile = Environment.ExpandEnvironmentVariables(@\"{0}\");{2}if (string.Compare(\".\\\", 0, tgtFile, 0, 2) == 0) {{ tgtFile = System.AppDomain.CurrentDomain.BaseDirectory + tgtFile.Substring(2); }}{2}try {{ tgtDir = System.IO.Path.GetDirectoryName(tgtFile);{2}if (tgtDir != string.Empty) {{ System.IO.Directory.CreateDirectory(tgtDir); }}{2}System.IO.File.WriteAllText(tgtFile, Expand_text(@\"{1}\"),Encoding.UTF8);{2}}}{2}catch {{ throw new System.IO.IOException(\"Error creating ''\" + tgtFile + \"''\r\n\"); }}{2}", src, content, Environment.NewLine)); |
|
// System.IO.File.WriteAllText(tgtFile, Expand_text(@\"{1}\"),Encoding.UTF8); |
|
// using (System.IO.Stream tgtStream = new System.IO.FileStream(tgtFile, System.IO.FileMode.Create)) {{ executingAssembly.GetManifestResourceStream(\"{1}\").CopyTo(tgtStream); }} // System.IO.Path.GetFileName(tgt) => content |
|
i++; |
|
} |
|
if (errfile.Count > 0) MessageBox.Show("Error reading file(s): " + string.Join(", ", errfile), "Compile", MessageBoxButton.OK, MessageBoxImage.Warning); |
|
if (i > 0) return sb.ToString(); else return ""; |
|
} // Create_embedFileSection |
|
|
|
private static string Get_sourcecontent(ps2exedotnet.UserOptions options) |
|
{ |
|
string scriptstring = System.IO.File.ReadAllText(options.inputscript); |
|
if (!options.nocompress) |
|
{ |
|
scriptstring = Compress_PSscriptblock(scriptstring, options.basic); |
|
if (options.preparedebug && scriptstring != "") |
|
{ |
|
string fn = Regex.Replace(options.inputscript,@"\.ps1$","-min.ps1", RegexOptions.IgnoreCase); |
|
if (fn != options.inputscript) System.IO.File.WriteAllLines(fn, new[] { scriptstring }, Encoding.UTF8); |
|
} |
|
} |
|
|
|
string fl = scriptstring.Substring(0,scriptstring.IndexOf(Environment.NewLine)); |
|
if (Regex.IsMatch(fl,@"#Requires\s+-Version\s+[67]", RegexOptions.IgnoreCase)) |
|
MessageBox.Show(@"Input script contains ""#Requires -Version"" directive that may at least prevent correct working of the output executable.", "Compile", MessageBoxButton.OK, MessageBoxImage.Warning); |
|
|
|
return Compress_text(scriptstring); |
|
} // Get_sourcecontent |
|
|
|
// NOTE: not sure if it's proper way |
|
private static string[] Add_assembly(ps2exedotnet.UserOptions options) |
|
{ |
|
// work around |
|
List<string> asmlist = new List<string>() {"System.dll"}; |
|
string al = Find_assembly("System.Management.Automation.dll"); |
|
if (al != "") asmlist.Add(al); |
|
al = Find_assembly("System.Core.dll","v4.0_4.0.0.0__b77a5c561934e089"); |
|
if (al != "") asmlist.Add(al); |
|
if (options.noconsole) { |
|
al = Find_assembly("System.Windows.Forms.dll","v4.0_4.0.0.0__b77a5c561934e089"); |
|
if (al != "") asmlist.Add(al); |
|
al = Find_assembly("System.Drawing.dll","v4.0_4.0.0.0__b03f5f7f11d50a3a"); |
|
if (al != "") asmlist.Add(al); |
|
} else { |
|
al = Find_assembly("Microsoft.PowerShell.ConsoleHost.dll"); |
|
if (al != "") asmlist.Add(al); |
|
} |
|
// ISSUE: AppDomain is for .NET only |
|
/*Assembly[] rawlist = AppDomain.CurrentDomain.GetAssemblies(); |
|
List<string> asmlist = new List<string>() {"System.dll"}; |
|
var asse = Array.Find(rawlist,e => e.ManifestModule.Name == "System.Management.Automation.dll"); |
|
if (asse != null) asmlist.Add(asse.Location); |
|
|
|
AssemblyName an = new AssemblyName("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); |
|
Assembly assembly = AppDomain.CurrentDomain.Load(an); |
|
asse = Array.Find(rawlist,e => e.ManifestModule.Name == "System.Core.dll"); |
|
if (asse != null) asmlist.Add(asse.Location); |
|
|
|
if (options.noconsole) { |
|
an = new AssemblyName("System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); |
|
assembly = AppDomain.CurrentDomain.Load(an); |
|
|
|
an = new AssemblyName("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); |
|
assembly = AppDomain.CurrentDomain.Load(an); |
|
|
|
rawlist = AppDomain.CurrentDomain.GetAssemblies(); |
|
asse = Array.Find(rawlist, e => e.ManifestModule.Name == "System.Windows.Forms.dll"); |
|
if (asse != null) asmlist.Add(asse.Location); |
|
asse = Array.Find(rawlist, e => e.ManifestModule.Name == "System.Drawing.dll"); |
|
if (asse != null) asmlist.Add(asse.Location); |
|
} else { |
|
asse = Array.Find(rawlist,e => e.ManifestModule.Name == "Microsoft.PowerShell.ConsoleHost.dll"); |
|
if (asse != null) asmlist.Add(asse.Location); |
|
}*/ |
|
|
|
return asmlist.ToArray(); |
|
} // add_assembly |
|
|
|
// a dirty way to fetch assembly names; experimental |
|
private static string Find_assembly(string name, string token=null) |
|
{ |
|
string agac = @"C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL"; |
|
//if (string.Equals(System.IO.Path.GetExtension(name), ".dll", StringComparison.OrdinalIgnoreCase)) |
|
if (Regex.IsMatch(name, @"\.dll$", RegexOptions.IgnoreCase)) |
|
name = Regex.Replace(name, @"\.dll$", "", RegexOptions.IgnoreCase); |
|
string aroot = string.Join(@"\", agac, name); |
|
if (!System.IO.Directory.Exists(aroot)) return ""; |
|
string[] dl; |
|
if (token == null) dl = System.IO.Directory.GetDirectories(aroot); |
|
else dl = System.IO.Directory.GetDirectories(aroot,token); |
|
if (dl == null) return ""; |
|
dl = System.IO.Directory.GetFiles(dl[0],@"*.dll"); |
|
if (dl == null || dl.Length == 0) return ""; |
|
return dl[0]; |
|
} // Find_assembly |
|
|
|
private static void Export_manifest(ps2exedotnet.UserOptions options, string mtype) |
|
{ |
|
string fn; |
|
if (mtype == "win32") |
|
{ |
|
List<string> win32manifest = new List<string>(); |
|
win32manifest.AddRange(new[] {"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>","<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"}); |
|
if (options.dpi || options.longpaths) |
|
{ |
|
win32manifest.AddRange(new[] {"<application xmlns=\"urn:schemas-microsoft-com:asm.v3\">","<windowsSettings>"}); |
|
if (options.dpi) |
|
{ |
|
win32manifest.AddRange(new[] {"<dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true</dpiAware>","<dpiAwareness xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">PerMonitorV2</dpiAwareness>"}); |
|
} |
|
if (options.longpaths) |
|
{ |
|
win32manifest.Add("<longPathAware xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">true</longPathAware>"); |
|
} |
|
} |
|
if (options.admin) |
|
{ |
|
win32manifest.AddRange(new[] {"<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v2\">","<security>","<requestedPrivileges xmlns=\"urn:schemas-microsoft-com:asm.v3\">","<requestedExecutionLevel level=\"requireAdministrator\" uiAccess=\"false\"/>","</requestedPrivileges>","</security>","</trustInfo>"}); |
|
} |
|
if (options.supportos) |
|
{ |
|
win32manifest.AddRange(new[] {"<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">","<application>","<supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\"/>","<supportedOS Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\"/>","<supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\"/>","<supportedOS Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\"/>","<supportedOS Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\"/>","</application>","</compatibility>"}); |
|
} |
|
win32manifest.Add("</assembly>"); |
|
fn = string.Concat(options.outputfile,".win32manifest"); |
|
System.IO.File.WriteAllLines(fn,win32manifest,Encoding.UTF8); |
|
return; |
|
} |
|
else if (mtype != "exe3") return; |
|
|
|
List<string> configFileForEXE3 = new List<string>(); |
|
string x = "4.0"; |
|
if (options.winformsdpi) x = "4.7"; |
|
configFileForEXE3.AddRange(new[] {"<?xml version=\"1.0\" encoding=\"utf-8\" ?>","<configuration><startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v"+x+"\" /></startup>"}); |
|
if (options.longpaths) |
|
{ |
|
configFileForEXE3.Add("<runtime><AppContextSwitchOverrides value=\"Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false\" /></runtime>"); |
|
} |
|
if (options.winformsdpi) |
|
{ |
|
configFileForEXE3.Add("<System.Windows.Forms.ApplicationConfigurationSection><add key=\"DpiAwareness\" value=\"PerMonitorV2\" /></System.Windows.Forms.ApplicationConfigurationSection>"); |
|
} |
|
configFileForEXE3.Add("</configuration>"); |
|
fn = string.Concat(options.outputfile,".config"); |
|
System.IO.File.WriteAllLines(fn,configFileForEXE3,Encoding.UTF8); |
|
} // Export_manifest |
|
|
|
private static string Get_MainProgramSource(ps2exedotnet.UserOptions parameters, ref CompilerParameters cp) |
|
{ |
|
System.Windows.Resources.StreamResourceInfo res = Application.GetResourceStream(new Uri("csframe.txt", UriKind.Relative)); |
|
if (res == null || res.Stream == null) |
|
{ |
|
MessageBox.Show("Resource 'csframe.txt' not found or empty", "Compile", MessageBoxButton.OK, MessageBoxImage.Error); |
|
return ""; |
|
} |
|
System.IO.StreamReader resreader = new System.IO.StreamReader(res.Stream, System.Text.Encoding.UTF8); |
|
string csframe = Expand_text(resreader.ReadToEnd()); |
|
|
|
// template {{preprocessor}} |
|
List<string> preprocessor = new List<string>(); |
|
if (parameters.noconsole) preprocessor.Add("#define noConsole"); |
|
if (parameters.winformsdpi) preprocessor.Add("#define winFormsDpiAware"); |
|
if (parameters.credgui) preprocessor.Add("#define credentialGUI"); |
|
if (parameters.novisualstyles) preprocessor.Add("#define noVisualStyles"); |
|
if (parameters.exitoncancel) preprocessor.Add("#define exitOnCancel"); |
|
if (parameters.nooutput) preprocessor.Add("#define noOutput"); |
|
if (parameters.noerror) preprocessor.Add("#define noError"); |
|
if (parameters.conhost) preprocessor.Add("#define conHost"); |
|
if (!parameters.mta) preprocessor.Add("#define STA"); |
|
if (parameters.unicode) preprocessor.Add("#define unicode"); |
|
if (parameters.title != "") preprocessor.Add("#define title"); |
|
|
|
// normalize metadata |
|
parameters.title = parameters.title.Replace(@"\",@"\\"); |
|
parameters.product = parameters.product.Replace(@"\",@"\\"); |
|
parameters.copyright = parameters.copyright.Replace(@"\",@"\\"); |
|
parameters.trademark = parameters.trademark.Replace(@"\",@"\\"); |
|
parameters.description = parameters.description.Replace(@"\",@"\\"); |
|
parameters.company = parameters.company.Replace(@"\",@"\\"); |
|
// template {{metadata}} |
|
List<string> metadata = new List<string>(); |
|
if (parameters.title != "") metadata.Add(string.Format(@"[assembly:AssemblyTitle(""{0}"")]",parameters.title)); |
|
if (parameters.product != "") metadata.Add(string.Format(@"[assembly:AssemblyProduct(""{0}"")]",parameters.product)); |
|
if (parameters.copyright != "") metadata.Add(string.Format(@"[assembly:AssemblyCopyright(""{0}"")]",parameters.copyright)); |
|
if (parameters.trademark != "") metadata.Add(string.Format(@"[assembly:AssemblyTrademark(""{0}"")]",parameters.trademark)); |
|
if (parameters.fileversion != "") |
|
{ |
|
metadata.Add(string.Format(@"[assembly:AssemblyVersion(""{0}"")]",parameters.fileversion)); |
|
metadata.Add(string.Format(@"[assembly:AssemblyFileVersion(""{0}"")]",parameters.fileversion)); |
|
} |
|
if (parameters.description != "" || parameters.company != "") |
|
{ |
|
metadata.Add("// not displayed in details tab of properties dialog, but embedded to file"); |
|
if (parameters.description != "") metadata.Add(string.Format(@"[assembly:AssemblyDescription(""{0}"")]", parameters.description)); |
|
if (parameters.company != "") metadata.Add(string.Format(@"[assembly:AssemblyCompany(""{0}"")]", parameters.company)); |
|
} |
|
|
|
// template {{culture}} |
|
string culture = ""; |
|
if (parameters.locale != "") { |
|
culture = string.Format("System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo({0});\r\nSystem.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo({0});",parameters.locale); |
|
} |
|
|
|
// template {{embedFileSection}} |
|
string embedFileSection = Create_embedFileSection(parameters, ref cp); |
|
|
|
// template {{sourceScript}} |
|
/*experimental: file as resource; / |
|
string sourceScript = System.IO.Path.GetTempFileName(); |
|
////parameters.tempInput = sourceScript; |
|
string sc = Get_sourcecontent(parameters); |
|
System.IO.File.WriteAllLines(sourceScript, new[] { sc }, Encoding.UTF8); |
|
cp.EmbeddedResources.Add(sourceScript);*/ |
|
string sourceScript = Get_sourcecontent(parameters); |
|
if (string.IsNullOrEmpty(sourceScript)) MessageBox.Show("The source script is empty", "Compile", MessageBoxButton.OK, MessageBoxImage.Warning); |
|
|
|
// replace placeholders and assemble the final string without "changing" immutable string |
|
// substitution placeholder is /*{{id}}*/ |
|
// NOTE: output string assembling depends on the amount and placeholders order |
|
string[] slices = Regex.Split(csframe,@"/\*\{\{.+\}\}\*/"); |
|
return string.Concat( |
|
slices[0],string.Join(Environment.NewLine, preprocessor), |
|
slices[1],string.Join(Environment.NewLine, metadata), |
|
slices[2],culture, |
|
slices[3],embedFileSection, |
|
slices[4],sourceScript, |
|
slices[5] |
|
); |
|
} // Get_MainProgramSource |
|
|
|
//public void Invoke_DomCompiler() {} // Invoke_DomCompiler() |
|
//public void Invoke_DotnetCompiler() {} // Invoke_DotnetCompiler() |
|
} // Ps2Exe class |
|
} // Ps2Exe namespace |
|
|
|
namespace OpenFolderDialog // to be replaced with modern one |
|
{ |
|
internal class OpenFolderDialog : IDisposable |
|
{ |
|
public string InitialFolder { get; set; } |
|
public string DefaultFolder { get; set; } |
|
public string Folder { get; private set; } |
|
|
|
internal Nullable<bool> ShowDialog() |
|
{ |
|
return ShowDialog(IntPtr.Zero); |
|
} |
|
|
|
internal Nullable<bool> ShowDialog(IntPtr ownerHandle) |
|
{ |
|
var frm = (NativeMethods.IFileDialog)(new NativeMethods.FileOpenDialogRCW()); |
|
uint options; |
|
frm.GetOptions(out options); |
|
options |= NativeMethods.FOS_PICKFOLDERS | NativeMethods.FOS_FORCEFILESYSTEM | NativeMethods.FOS_NOVALIDATE | NativeMethods.FOS_NOTESTFILECREATE | NativeMethods.FOS_DONTADDTORECENT; |
|
frm.SetOptions(options); |
|
if (this.InitialFolder != null) |
|
{ |
|
NativeMethods.IShellItem directoryShellItem; |
|
var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem |
|
if (NativeMethods.SHCreateItemFromParsingName(this.InitialFolder, IntPtr.Zero, ref riid, out directoryShellItem) == NativeMethods.S_OK) |
|
{ |
|
frm.SetFolder(directoryShellItem); |
|
} |
|
} |
|
if (this.DefaultFolder != null) |
|
{ |
|
NativeMethods.IShellItem directoryShellItem; |
|
var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem |
|
if (NativeMethods.SHCreateItemFromParsingName(this.DefaultFolder, IntPtr.Zero, ref riid, out directoryShellItem) == NativeMethods.S_OK) |
|
{ |
|
frm.SetDefaultFolder(directoryShellItem); |
|
} |
|
} |
|
|
|
if (frm.Show(ownerHandle) == NativeMethods.S_OK) |
|
{ |
|
NativeMethods.IShellItem shellItem; |
|
if (frm.GetResult(out shellItem) == NativeMethods.S_OK) |
|
{ |
|
IntPtr pszString; |
|
if (shellItem.GetDisplayName(NativeMethods.SIGDN_FILESYSPATH, out pszString) == NativeMethods.S_OK) |
|
{ |
|
if (pszString != IntPtr.Zero) |
|
{ |
|
try { |
|
this.Folder = Marshal.PtrToStringAuto(pszString); |
|
return true; |
|
} |
|
finally { |
|
Marshal.FreeCoTaskMem(pszString); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
public void Dispose() { } // just to have the possibility of the using statement |
|
} |
|
|
|
internal static class NativeMethods |
|
{ |
|
public const uint FOS_PICKFOLDERS = 0x00000020; |
|
public const uint FOS_FORCEFILESYSTEM = 0x00000040; |
|
public const uint FOS_NOVALIDATE = 0x00000100; |
|
public const uint FOS_NOTESTFILECREATE = 0x00010000; |
|
public const uint FOS_DONTADDTORECENT = 0x02000000; |
|
public const uint S_OK = 0x0000; |
|
public const uint SIGDN_FILESYSPATH = 0x80058000; |
|
|
|
[ComImport, ClassInterface(ClassInterfaceType.None), TypeLibType(TypeLibTypeFlags.FCanCreate), Guid("DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7")] |
|
internal class FileOpenDialogRCW { } |
|
|
|
[ComImport(), Guid("42F85136-DB7E-439C-85F1-E4075D135FC8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
|
internal interface IFileDialog |
|
{ |
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
[PreserveSig()] |
|
uint Show([In, Optional] IntPtr hwndOwner); // inherited from IModalWindow |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetFileTypes([In] uint cFileTypes, [In, MarshalAs(UnmanagedType.LPArray)] IntPtr rgFilterSpec); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetFileTypeIndex([In] uint iFileType); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint GetFileTypeIndex(out uint piFileType); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint Advise([In, MarshalAs(UnmanagedType.Interface)] IntPtr pfde, out uint pdwCookie); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint Unadvise([In] uint dwCookie); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetOptions([In] uint fos); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint GetOptions(out uint fos); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, uint fdap); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint Close([MarshalAs(UnmanagedType.Error)] uint hr); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetClientGuid([In] ref Guid guid); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint ClearClientData(); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter); |
|
} |
|
|
|
[ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
|
internal interface IShellItem |
|
{ |
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint BindToHandler([In] IntPtr pbc, [In] ref Guid rbhid, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IntPtr ppvOut); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint GetDisplayName([In] uint sigdnName, out IntPtr ppszName); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint GetAttributes([In] uint sfgaoMask, out uint psfgaoAttribs); |
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] |
|
uint Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, [In] uint hint, out int piOrder); |
|
} |
|
|
|
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)] |
|
internal static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppv); |
|
} |
|
} // end OpenFolderDialog |