Skip to content

Commit f943004

Browse files
Create AdminMenu.cs
1 parent 29b535b commit f943004

File tree

1 file changed

+227
-0
lines changed

1 file changed

+227
-0
lines changed

VisualStudio/AdminMenu.cs

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.IO;
5+
using System.Xml;
6+
using System.Windows.Forms;
7+
using System.Reflection;
8+
using MahApps.Metro.Controls;
9+
10+
namespace PSAdminMenu
11+
{
12+
static class AdminMenu
13+
{
14+
[STAThread]
15+
public static void Main()
16+
{
17+
try
18+
{
19+
// Set up variables
20+
int processExitCode = 60010;
21+
string currentAppPath = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
22+
string currentAppFolder = Path.GetDirectoryName(currentAppPath);
23+
string appScriptPath = Path.Combine(currentAppFolder, "AdminMenu.ps1");
24+
string appExtensionFolder = Path.Combine(currentAppFolder, "Extensions");
25+
string appXamlFolder = Path.Combine(currentAppFolder, "Resources");
26+
string appXMLPath = Path.Combine(currentAppFolder, "AdminMenu.ps1.config");
27+
string powershellExePath = Path.Combine(Environment.GetEnvironmentVariable("WinDir"), "System32\\WindowsPowerShell\\v1.0\\PowerShell.exe");
28+
string powershellArgs = "-ExecutionPolicy Bypass -NoProfile -NoLogo -sta -WindowStyle Hidden";
29+
List<string> commandLineArgs = new List<string>(Environment.GetCommandLineArgs());
30+
bool isForceX86Mode = false;
31+
bool isRequireAdmin = false;
32+
33+
// Load Metro Assemblys
34+
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
35+
var resourceName = Assembly.GetExecutingAssembly().GetName().Name + ".Assemblies." + new AssemblyName(args.Name).Name + ".dll";
36+
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
37+
{
38+
if (stream != null)
39+
{
40+
var assemblyData = new Byte[stream.Length];
41+
stream.Read(assemblyData, 0, assemblyData.Length);
42+
return Assembly.Load(assemblyData);
43+
}
44+
}
45+
return null;
46+
};
47+
48+
// Get OS Architecture. Check does not return correct value when running in x86 process on x64 system but it works for our purpose.
49+
// To get correct OS architecture when running in x86 process on x64 system, we would also have to check environment variable: PROCESSOR_ARCHITEW6432.
50+
bool is64BitOS = false;
51+
if (Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE").Contains("64"))
52+
is64BitOS = true;
53+
54+
// Trim ending & starting empty space from each element in the command-line
55+
commandLineArgs = commandLineArgs.ConvertAll(s => s.Trim());
56+
// Remove first command-line argument as this is always the executable name
57+
commandLineArgs.RemoveAt(0);
58+
59+
// Check if x86 PowerShell mode was specified on command line
60+
if (commandLineArgs.Exists(x => x == "/32"))
61+
{
62+
isForceX86Mode = true;
63+
WriteDebugMessage("'/32' parameter was specified on the command-line. Running in forced x86 PowerShell mode...");
64+
// Remove the /32 command line argument so that it is not passed to PowerShell script
65+
commandLineArgs.RemoveAll(x => x == "/32");
66+
}
67+
68+
if (commandLineArgs.Exists(x => x.StartsWith("-ForceLocal")))
69+
{
70+
WriteDebugMessage("'-ForceLocal' parameter was specified on the command-line. Running in forced config local mode...");
71+
}
72+
73+
// Check for the App Config file being specified
74+
string commandLineAppXMLPathArg = String.Empty;
75+
if (commandLineArgs.Exists(x => x.StartsWith("-Config ")))
76+
{
77+
commandLineAppXMLPathArg = commandLineArgs.Find(x => x.StartsWith("-Config "));
78+
appXMLPath = commandLineAppXMLPathArg.Replace("-Config ", String.Empty).Replace("\"", String.Empty);
79+
if (!Path.IsPathRooted(appXMLPath))
80+
appXMLPath = Path.Combine(currentAppFolder, appXMLPath);
81+
// commandLineArgs.RemoveAt(commandLineArgs.FindIndex(x => x.StartsWith("-Config")));
82+
WriteDebugMessage("'-Config' parameter specified on command-line. Passing command-line untouched...");
83+
}
84+
else if (commandLineArgs.Exists(x => x.EndsWith(".config") || x.EndsWith(".config\"")))
85+
{
86+
appXMLPath = commandLineArgs.Find(x => x.EndsWith(".config") || x.EndsWith(".config\"")).Replace("\"", String.Empty);
87+
if (!Path.IsPathRooted(appXMLPath))
88+
appXMLPath = Path.Combine(currentAppFolder, appXMLPath);
89+
// commandLineArgs.RemoveAt(commandLineArgs.FindIndex(x => x.EndsWith(".config") || x.EndsWith(".config\"")));
90+
WriteDebugMessage(".config file specified on command-line. Appending '-Config' parameter name...");
91+
}
92+
else
93+
{
94+
WriteDebugMessage("No '-Config' parameter specified on command-line. Adding parameter '-Config \"" + appXMLPath + "\"'...");
95+
}
96+
97+
// Define the command line arguments to pass to PowerShell
98+
powershellArgs = powershellArgs + " -Command & { & '" + appScriptPath + "'";
99+
if (commandLineArgs.Count > 0)
100+
{
101+
powershellArgs = powershellArgs + " " + string.Join(" ", commandLineArgs.ToArray());
102+
}
103+
powershellArgs = powershellArgs + "; Exit $LastExitCode }";
104+
105+
// Verify if the App Script file exists
106+
if (!File.Exists(appScriptPath))
107+
{
108+
throw new Exception("A critical component of the Admin Run-As Menu is missing." + Environment.NewLine + Environment.NewLine + "Unable to find the 'AdminMenu.ps1' Script file: " + appScriptPath + "." + Environment.NewLine + Environment.NewLine + "Please ensure you have all of the required files available to start the installation.");
109+
}
110+
111+
// Verify if the Admin Run-As Menu Extensions folder exists
112+
if (!Directory.Exists(appExtensionFolder))
113+
{
114+
throw new Exception("A critical component of the Admin Run-As Menu is missing." + Environment.NewLine + Environment.NewLine + "Unable to find the 'Extensions' folder." + Environment.NewLine + Environment.NewLine + "Please ensure you have all of the required folders available to start the installation.");
115+
}
116+
117+
// Verify if the Admin Run-As Menu Resources exists
118+
if (!Directory.Exists(appXamlFolder))
119+
{
120+
throw new Exception("A critical component of the Admin Run-As Menu is missing." + Environment.NewLine + Environment.NewLine + "Unable to find the 'Resources' folder." + Environment.NewLine + Environment.NewLine + "Please ensure you have all of the required folders available to start the installation.");
121+
}
122+
123+
// Verify if the Admin Run-As Menu Extensions Config XML file exists
124+
if (!File.Exists(appXMLPath))
125+
{
126+
throw new Exception("A critical component of the Admin Run-As Menu is missing." + Environment.NewLine + Environment.NewLine + "Unable to find the 'AdminMenu.ps1.config' file." + Environment.NewLine + Environment.NewLine + "Please ensure you have all of the required files available to start the installation.");
127+
}
128+
else
129+
{
130+
// Read the XML and determine whether we need Admin Rights
131+
XmlDocument xml = new XmlDocument();
132+
xml.Load(appXMLPath);
133+
XmlNode xmlNode = null;
134+
XmlElement xmlRoot = xml.DocumentElement;
135+
xmlNode = xmlRoot.SelectSingleNode("/AdminMenu_Configs/Menu_Options/Option_RequireAdmin");
136+
isRequireAdmin = Convert.ToBoolean(xmlNode.InnerText);
137+
if (isRequireAdmin)
138+
{
139+
WriteDebugMessage("Administrator rights are required...");
140+
}
141+
}
142+
143+
// Switch to x86 PowerShell if requested
144+
if (is64BitOS & isForceX86Mode)
145+
{
146+
powershellExePath = Path.Combine(Environment.GetEnvironmentVariable("WinDir"), "SysWOW64\\WindowsPowerShell\\v1.0\\PowerShell.exe");
147+
}
148+
149+
// Define PowerShell process
150+
WriteDebugMessage("PowerShell Path: " + powershellExePath);
151+
WriteDebugMessage("PowerShell Parameters: " + powershellArgs);
152+
ProcessStartInfo processStartInfo = new ProcessStartInfo();
153+
processStartInfo.FileName = powershellExePath;
154+
processStartInfo.Arguments = powershellArgs;
155+
processStartInfo.WorkingDirectory = Path.GetDirectoryName(powershellExePath);
156+
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
157+
processStartInfo.UseShellExecute = true;
158+
// Set the RunAs flag if the XML specifically calls for Admin Rights and OS Vista or higher
159+
if (((isRequireAdmin) & (Environment.OSVersion.Version.Major >= 6)))
160+
{
161+
processStartInfo.Verb = "runas";
162+
}
163+
164+
// Start the PowerShell process and wait for completion
165+
processExitCode = 60011;
166+
Process process = new Process();
167+
try
168+
{
169+
process.StartInfo = processStartInfo;
170+
process.Start();
171+
process.WaitForExit();
172+
processExitCode = process.ExitCode;
173+
}
174+
catch (Exception)
175+
{
176+
throw;
177+
}
178+
finally
179+
{
180+
if ((process != null))
181+
{
182+
process.Dispose();
183+
}
184+
}
185+
186+
// Exit
187+
WriteDebugMessage("Exit Code: " + processExitCode);
188+
Environment.Exit(processExitCode);
189+
}
190+
catch (Exception ex)
191+
{
192+
WriteDebugMessage(ex.Message, true, MessageBoxIcon.Error);
193+
Environment.Exit(processExitCode);
194+
}
195+
}
196+
197+
public static void WriteDebugMessage(string debugMessage = null, bool IsDisplayError = false, MessageBoxIcon MsgBoxStyle = MessageBoxIcon.Information)
198+
{
199+
// Output to the Console
200+
Console.WriteLine(debugMessage);
201+
202+
// If we are to display an error message...
203+
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
204+
if (IsDisplayError == true)
205+
{
206+
MessageBox.Show(new WindowWrapper(handle), debugMessage, Application.ProductName + " " + Application.ProductVersion, MessageBoxButtons.OK, (MessageBoxIcon)MsgBoxStyle, MessageBoxDefaultButton.Button1);
207+
}
208+
}
209+
210+
public class WindowWrapper : System.Windows.Forms.IWin32Window
211+
{
212+
public WindowWrapper(IntPtr handle)
213+
{
214+
_hwnd = handle;
215+
}
216+
217+
public IntPtr Handle
218+
{
219+
get { return _hwnd; }
220+
}
221+
222+
private IntPtr _hwnd;
223+
}
224+
225+
public static int processExitCode { get; set; }
226+
}
227+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy