-
-
Save spenkk/2dfd76780b87347477d230470e3e38c2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
| <Target Name="MSBuildPosh"> | |
| <MSBuildShell/> | |
| </Target> | |
| <UsingTask | |
| TaskName="MSBuildShell" | |
| TaskFactory="CodeTaskFactory" | |
| AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" > | |
| <Task> | |
| <Reference Include="System.Management.Automation" /> | |
| <Code Type="Class" Language="cs"> | |
| <![CDATA[ | |
| using System; | |
| using System.IO; | |
| using System.Text; | |
| using System.Linq; | |
| using System.Globalization; | |
| using System.Reflection; | |
| using System.Security; | |
| using Microsoft.Win32; | |
| using Microsoft.Build.Framework; | |
| using Microsoft.Build.Utilities; | |
| using System.ComponentModel; | |
| using System.Collections.Generic; | |
| using System.Collections.ObjectModel; | |
| using System.Runtime.InteropServices; | |
| using System.Management.Automation; | |
| using System.Management.Automation.Host; | |
| using System.Management.Automation.Runspaces; | |
| using PowerShell = System.Management.Automation.PowerShell; | |
| public class MSBuildShell : Task, ITask | |
| { | |
| [DllImport("ntdll.dll")] | |
| private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation); | |
| [StructLayout(LayoutKind.Sequential)] | |
| internal struct RTL_OSVERSIONINFOEX | |
| { | |
| internal uint dwOSVersionInfoSize; | |
| internal uint dwMajorVersion; | |
| internal uint dwMinorVersion; | |
| internal uint dwBuildNumber; | |
| internal uint dwPlatformId; | |
| [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] | |
| internal string szCSDVersion; | |
| } | |
| public static decimal RtlGetVersion() | |
| { | |
| RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX(); | |
| osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); | |
| //const string version = "Microsoft Windows"; | |
| if (RtlGetVersion(out osvi) == 0) | |
| { | |
| string Version = osvi.dwMajorVersion + "." + osvi.dwMinorVersion; | |
| return decimal.Parse(Version, CultureInfo.InvariantCulture); | |
| } | |
| else | |
| { | |
| return -1; | |
| } | |
| } | |
| public static void PrintBanner() | |
| { | |
| Console.BackgroundColor = ConsoleColor.DarkBlue; | |
| Console.ForegroundColor = ConsoleColor.White; | |
| Console.Clear(); | |
| Console.WriteLine("Windows MSBuildShell"); | |
| Console.WriteLine(); | |
| } | |
| private static PowerListenerConsole PowerListener = new PowerListenerConsole(); | |
| public override bool Execute() | |
| { | |
| Console.Title = "Windows MSBuildShell"; | |
| PrintBanner(); | |
| string LatestOSVersion = "6.3"; | |
| decimal latestOSVersionDec = decimal.Parse(LatestOSVersion, CultureInfo.InvariantCulture); | |
| PowerListener.CommandShell(); | |
| return true; | |
| } | |
| } | |
| class PowerListenerConsole | |
| { | |
| private bool shouldExit; | |
| private int exitCode; | |
| private MyHost myHost; | |
| internal Runspace myRunSpace; | |
| private PowerShell currentPowerShell; | |
| private object instanceLock = new object(); | |
| public PowerListenerConsole() | |
| { | |
| InitialSessionState state = InitialSessionState.CreateDefault(); | |
| state.AuthorizationManager = new System.Management.Automation.AuthorizationManager("Dummy"); | |
| this.myHost = new MyHost(this); | |
| this.myRunSpace = RunspaceFactory.CreateRunspace(this.myHost, state); | |
| this.myRunSpace.Open(); | |
| lock (this.instanceLock) | |
| { | |
| this.currentPowerShell = PowerShell.Create(); | |
| } | |
| try | |
| { | |
| this.currentPowerShell.Runspace = this.myRunSpace; | |
| PSCommand[] profileCommands = HostUtilities.GetProfileCommands("PowerShell"); | |
| foreach (PSCommand command in profileCommands) | |
| { | |
| this.currentPowerShell.Commands = command; | |
| this.currentPowerShell.Invoke(); | |
| } | |
| } | |
| finally | |
| { | |
| lock (this.instanceLock) | |
| { | |
| this.currentPowerShell.Dispose(); | |
| this.currentPowerShell = null; | |
| } | |
| } | |
| } | |
| public bool ShouldExit | |
| { | |
| get { return this.shouldExit; } | |
| set { this.shouldExit = value; } | |
| } | |
| public int ExitCode | |
| { | |
| get { return this.exitCode; } | |
| set { this.exitCode = value; } | |
| } | |
| public void CommandShell() | |
| { | |
| PowerListenerConsole listener = new PowerListenerConsole(); | |
| listener.CommandPrompt(); | |
| } | |
| private void executeHelper(string cmd, object input) | |
| { | |
| if (String.IsNullOrEmpty(cmd)) | |
| { | |
| return; | |
| } | |
| lock (this.instanceLock) | |
| { | |
| this.currentPowerShell = PowerShell.Create(); | |
| } | |
| try | |
| { | |
| this.currentPowerShell.Runspace = this.myRunSpace; | |
| this.currentPowerShell.AddScript(cmd); | |
| this.currentPowerShell.AddCommand("out-default"); | |
| this.currentPowerShell.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output); | |
| if (input != null) | |
| { | |
| this.currentPowerShell.Invoke(new object[] { input }); | |
| } | |
| else | |
| { | |
| this.currentPowerShell.Invoke(); | |
| } | |
| } | |
| finally | |
| { | |
| lock (this.instanceLock) | |
| { | |
| this.currentPowerShell.Dispose(); | |
| this.currentPowerShell = null; | |
| } | |
| } | |
| } | |
| private void ReportException(Exception e) | |
| { | |
| if (e != null) | |
| { | |
| object error; | |
| IContainsErrorRecord icer = e as IContainsErrorRecord; | |
| if (icer != null) | |
| { | |
| error = icer.ErrorRecord; | |
| } | |
| else | |
| { | |
| error = (object)new ErrorRecord(e, "Host.ReportException", ErrorCategory.NotSpecified, null); | |
| } | |
| lock (this.instanceLock) | |
| { | |
| this.currentPowerShell = PowerShell.Create(); | |
| } | |
| this.currentPowerShell.Runspace = this.myRunSpace; | |
| try | |
| { | |
| this.currentPowerShell.AddScript("$input").AddCommand("out-string"); | |
| Collection<PSObject> result; | |
| PSDataCollection<object> inputCollection = new PSDataCollection<object>(); | |
| inputCollection.Add(error); | |
| inputCollection.Complete(); | |
| result = this.currentPowerShell.Invoke(inputCollection); | |
| if (result.Count > 0) | |
| { | |
| string str = result[0].BaseObject as string; | |
| if (!string.IsNullOrEmpty(str)) | |
| { | |
| this.myHost.UI.WriteErrorLine(str.Substring(0, str.Length - 2)); | |
| } | |
| } | |
| } | |
| finally | |
| { | |
| lock (this.instanceLock) | |
| { | |
| this.currentPowerShell.Dispose(); | |
| this.currentPowerShell = null; | |
| } | |
| } | |
| } | |
| } | |
| public void Execute(string cmd) | |
| { | |
| try | |
| { | |
| this.executeHelper(cmd, null); | |
| } | |
| catch (RuntimeException rte) | |
| { | |
| this.ReportException(rte); | |
| } | |
| } | |
| private void HandleControlC(object sender, ConsoleCancelEventArgs e) | |
| { | |
| try | |
| { | |
| lock (this.instanceLock) | |
| { | |
| if (this.currentPowerShell != null && this.currentPowerShell.InvocationStateInfo.State == PSInvocationState.Running) | |
| { | |
| this.currentPowerShell.Stop(); | |
| } | |
| } | |
| e.Cancel = true; | |
| } | |
| catch (Exception exception) | |
| { | |
| this.myHost.UI.WriteErrorLine(exception.ToString()); | |
| } | |
| } | |
| private void CommandPrompt() | |
| { | |
| int bufSize = 8192; | |
| Stream inStream = Console.OpenStandardInput(bufSize); | |
| Console.SetIn(new StreamReader(inStream, Console.InputEncoding, false, bufSize)); | |
| Console.CancelKeyPress += new ConsoleCancelEventHandler(this.HandleControlC); | |
| Console.TreatControlCAsInput = false; | |
| while (!this.ShouldExit) | |
| { | |
| string prompt; | |
| if (this.myHost.IsRunspacePushed) | |
| { | |
| prompt = string.Format("[{0}]: PS> ", this.myRunSpace.ConnectionInfo.ComputerName); | |
| } | |
| else | |
| { | |
| prompt = string.Format("PS {0}> ", this.myRunSpace.SessionStateProxy.Path.CurrentFileSystemLocation.Path); | |
| } | |
| this.myHost.UI.Write(prompt); | |
| string cmd = Console.ReadLine(); | |
| if (cmd == "exit" || cmd == "quit") | |
| { | |
| return; | |
| } | |
| else if (cmd == "cls") | |
| { | |
| Console.Clear(); | |
| } | |
| else | |
| { | |
| try | |
| { | |
| this.Execute(cmd); | |
| } | |
| catch (Exception e) | |
| { | |
| Console.WriteLine(e.Message); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| internal class MyHost : PSHost, IHostSupportsInteractiveSession | |
| { | |
| public Runspace pushedRunspace = null; | |
| public MyHost(PowerListenerConsole program) | |
| { | |
| this.program = program; | |
| } | |
| private static Guid instanceId = Guid.NewGuid(); | |
| private PowerListenerConsole program; | |
| private CultureInfo originalCultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture; | |
| private CultureInfo originalUICultureInfo = System.Threading.Thread.CurrentThread.CurrentUICulture; | |
| private MyHostUserInterface myHostUserInterface = new MyHostUserInterface(); | |
| public override CultureInfo CurrentCulture | |
| { | |
| get { return this.originalCultureInfo; } | |
| } | |
| public override CultureInfo CurrentUICulture | |
| { | |
| get { return this.originalUICultureInfo; } | |
| } | |
| public override Guid InstanceId | |
| { | |
| get { return instanceId; } | |
| } | |
| public override string Name | |
| { | |
| get { return "MSBuildShell"; } | |
| } | |
| public override PSHostUserInterface UI | |
| { | |
| get { return this.myHostUserInterface; } | |
| } | |
| public override Version Version | |
| { | |
| get { return new Version(1, 0, 0, 0); } | |
| } | |
| #region IHostSupportsInteractiveSession Properties | |
| public bool IsRunspacePushed | |
| { | |
| get { return this.pushedRunspace != null; } | |
| } | |
| public Runspace Runspace | |
| { | |
| get { return this.program.myRunSpace; } | |
| internal set { this.program.myRunSpace = value; } | |
| } | |
| #endregion IHostSupportsInteractiveSession Properties | |
| public override void EnterNestedPrompt() | |
| { | |
| throw new NotImplementedException("Cannot suspend the shell, EnterNestedPrompt() method is not implemented by MyHost."); | |
| } | |
| public override void ExitNestedPrompt() | |
| { | |
| throw new NotImplementedException("The ExitNestedPrompt() method is not implemented by MyHost."); | |
| } | |
| public override void NotifyBeginApplication() | |
| { | |
| } | |
| public override void NotifyEndApplication() | |
| { | |
| } | |
| public override void SetShouldExit(int exitCode) | |
| { | |
| this.program.ShouldExit = true; | |
| this.program.ExitCode = exitCode; | |
| } | |
| #region IHostSupportsInteractiveSession Methods | |
| public void PopRunspace() | |
| { | |
| Runspace = this.pushedRunspace; | |
| this.pushedRunspace = null; | |
| } | |
| public void PushRunspace(Runspace runspace) | |
| { | |
| this.pushedRunspace = Runspace; | |
| Runspace = runspace; | |
| } | |
| #endregion IHostSupportsInteractiveSession Methods | |
| } | |
| internal class MyHostUserInterface : PSHostUserInterface, IHostUISupportsMultipleChoiceSelection | |
| { | |
| [DllImport("ole32.dll")] | |
| public static extern void CoTaskMemFree(IntPtr ptr); | |
| [DllImport("credui.dll", CharSet = CharSet.Auto)] | |
| private static extern int CredUIPromptForWindowsCredentials(ref CREDUI_INFO notUsedHere, int authError, ref uint authPackage, IntPtr InAuthBuffer, uint InAuthBufferSize, out IntPtr refOutAuthBuffer, out uint refOutAuthBufferSize, ref bool fSave, int flags); | |
| [DllImport("credui.dll", CharSet = CharSet.Auto)] | |
| private static extern bool CredUnPackAuthenticationBuffer(int dwFlags, IntPtr pAuthBuffer, uint cbAuthBuffer, StringBuilder pszUserName, ref int pcchMaxUserName, StringBuilder pszDomainName, ref int pcchMaxDomainame, StringBuilder pszPassword, ref int pcchMaxPassword); | |
| [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] | |
| private struct CREDUI_INFO | |
| { | |
| public int cbSize; | |
| public IntPtr hwndParent; | |
| public string pszMessageText; | |
| public string pszCaptionText; | |
| public IntPtr hbmBanner; | |
| } | |
| private MyRawUserInterface myRawUi = new MyRawUserInterface(); | |
| public override PSHostRawUserInterface RawUI | |
| { | |
| get { return this.myRawUi; } | |
| } | |
| public override Dictionary<string, PSObject> Prompt( | |
| string caption, | |
| string message, | |
| Collection<FieldDescription> descriptions) | |
| { | |
| this.Write( | |
| ConsoleColor.Blue, | |
| ConsoleColor.Black, | |
| caption + "\n" + message + " "); | |
| Dictionary<string, PSObject> results = | |
| new Dictionary<string, PSObject>(); | |
| foreach (FieldDescription fd in descriptions) | |
| { | |
| string[] label = GetHotkeyAndLabel(fd.Label); | |
| this.WriteLine(label[1]); | |
| string userData = Console.ReadLine(); | |
| if (userData == null) | |
| { | |
| return null; | |
| } | |
| results[fd.Name] = PSObject.AsPSObject(userData); | |
| } | |
| return results; | |
| } | |
| public override int PromptForChoice( | |
| string caption, | |
| string message, | |
| Collection<ChoiceDescription> choices, | |
| int defaultChoice) | |
| { | |
| this.WriteLine( | |
| ConsoleColor.Blue, | |
| ConsoleColor.Black, | |
| caption + "\n" + message + "\n"); | |
| string[,] promptData = BuildHotkeysAndPlainLabels(choices); | |
| StringBuilder sb = new StringBuilder(); | |
| for (int element = 0; element < choices.Count; element++) | |
| { | |
| sb.Append(String.Format( | |
| CultureInfo.CurrentCulture, | |
| "|{0}> {1} ", | |
| promptData[0, element], | |
| promptData[1, element])); | |
| } | |
| sb.Append(String.Format( | |
| CultureInfo.CurrentCulture, | |
| "[Default is ({0}]", | |
| promptData[0, defaultChoice])); | |
| while (true) | |
| { | |
| this.WriteLine(ConsoleColor.Cyan, ConsoleColor.Black, sb.ToString()); | |
| string data = Console.ReadLine().Trim().ToUpper(CultureInfo.CurrentCulture); | |
| if (data.Length == 0) | |
| { | |
| return defaultChoice; | |
| } | |
| for (int i = 0; i < choices.Count; i++) | |
| { | |
| if (promptData[0, i] == data) | |
| { | |
| return i; | |
| } | |
| } | |
| this.WriteErrorLine("Invalid choice: " + data); | |
| } | |
| } | |
| #region IHostUISupportsMultipleChoiceSelection Members | |
| public Collection<int> PromptForChoice( | |
| string caption, | |
| string message, | |
| Collection<ChoiceDescription> choices, | |
| IEnumerable<int> defaultChoices) | |
| { | |
| this.WriteLine( | |
| ConsoleColor.Blue, | |
| ConsoleColor.Black, | |
| caption + "\n" + message + "\n"); | |
| string[,] promptData = BuildHotkeysAndPlainLabels(choices); | |
| StringBuilder sb = new StringBuilder(); | |
| for (int element = 0; element < choices.Count; element++) | |
| { | |
| sb.Append(String.Format( | |
| CultureInfo.CurrentCulture, | |
| "|{0}> {1} ", | |
| promptData[0, element], | |
| promptData[1, element])); | |
| } | |
| Collection<int> defaultResults = new Collection<int>(); | |
| if (defaultChoices != null) | |
| { | |
| int countDefaults = 0; | |
| foreach (int defaultChoice in defaultChoices) | |
| { | |
| ++countDefaults; | |
| defaultResults.Add(defaultChoice); | |
| } | |
| if (countDefaults != 0) | |
| { | |
| sb.Append(countDefaults == 1 ? "[Default choice is " : "[Default choices are "); | |
| foreach (int defaultChoice in defaultChoices) | |
| { | |
| sb.AppendFormat( | |
| CultureInfo.CurrentCulture, | |
| "\"{0}\",", | |
| promptData[0, defaultChoice]); | |
| } | |
| sb.Remove(sb.Length - 1, 1); | |
| sb.Append("]"); | |
| } | |
| } | |
| this.WriteLine(ConsoleColor.Cyan, ConsoleColor.Black, sb.ToString()); | |
| Collection<int> results = new Collection<int>(); | |
| while (true) | |
| { | |
| ReadNext: | |
| string prompt = string.Format(CultureInfo.CurrentCulture, "Choice[{0}]:", results.Count); | |
| this.Write(ConsoleColor.Cyan, ConsoleColor.Black, prompt); | |
| string data = Console.ReadLine().Trim().ToUpper(CultureInfo.CurrentCulture); | |
| if (data.Length == 0) | |
| { | |
| return (results.Count == 0) ? defaultResults : results; | |
| } | |
| for (int i = 0; i < choices.Count; i++) | |
| { | |
| if (promptData[0, i] == data) | |
| { | |
| results.Add(i); | |
| goto ReadNext; | |
| } | |
| } | |
| this.WriteErrorLine("Invalid choice: " + data); | |
| } | |
| } | |
| #endregion | |
| public override PSCredential PromptForCredential( | |
| string caption, | |
| string message, | |
| string userName, | |
| string targetName) | |
| { | |
| PromptCredentialsResult result = CredentialUI.PromptForCredentials(targetName, caption, message, userName, null); | |
| return result == null ? null : new PSCredential(result.UserName, result.Password.ToSecureString()); | |
| } | |
| public override PSCredential PromptForCredential( | |
| string caption, | |
| string message, | |
| string userName, | |
| string targetName, | |
| PSCredentialTypes allowedCredentialTypes, | |
| PSCredentialUIOptions options) | |
| { | |
| PromptCredentialsResult result = CredentialUI.PromptForCredentials(targetName, caption, message, userName, null); | |
| return result == null ? null : new PSCredential(result.UserName, result.Password.ToSecureString()); | |
| } | |
| public override string ReadLine() | |
| { | |
| return Console.ReadLine(); | |
| } | |
| public override System.Security.SecureString ReadLineAsSecureString() | |
| { | |
| return Console.ReadLine().ToSecureString(); | |
| } | |
| public override void Write(string value) | |
| { | |
| Console.Write(value); | |
| } | |
| public override void Write( | |
| ConsoleColor foregroundColor, | |
| ConsoleColor backgroundColor, | |
| string value) | |
| { | |
| ConsoleColor oldFg = Console.ForegroundColor; | |
| ConsoleColor oldBg = Console.BackgroundColor; | |
| Console.ForegroundColor = foregroundColor; | |
| Console.BackgroundColor = backgroundColor; | |
| Console.Write(value); | |
| Console.ForegroundColor = oldFg; | |
| Console.BackgroundColor = oldBg; | |
| } | |
| public override void WriteLine( | |
| ConsoleColor foregroundColor, | |
| ConsoleColor backgroundColor, | |
| string value) | |
| { | |
| ConsoleColor oldFg = Console.ForegroundColor; | |
| ConsoleColor oldBg = Console.BackgroundColor; | |
| Console.ForegroundColor = foregroundColor; | |
| Console.BackgroundColor = backgroundColor; | |
| Console.WriteLine(value); | |
| Console.ForegroundColor = oldFg; | |
| Console.BackgroundColor = oldBg; | |
| } | |
| public override void WriteDebugLine(string message) | |
| { | |
| this.WriteLine( | |
| ConsoleColor.DarkYellow, | |
| ConsoleColor.Black, | |
| String.Format(CultureInfo.CurrentCulture, "DEBUG: {0}", message)); | |
| } | |
| public override void WriteErrorLine(string value) | |
| { | |
| this.WriteLine(ConsoleColor.Red, ConsoleColor.Black, value); | |
| } | |
| public override void WriteLine() | |
| { | |
| Console.WriteLine(); | |
| } | |
| public override void WriteLine(string value) | |
| { | |
| Console.WriteLine(value); | |
| } | |
| public override void WriteVerboseLine(string message) | |
| { | |
| this.WriteLine( | |
| ConsoleColor.Yellow, | |
| ConsoleColor.Black, | |
| String.Format(CultureInfo.CurrentCulture, "VERBOSE: {0}", message)); | |
| } | |
| public override void WriteWarningLine(string message) | |
| { | |
| this.WriteLine( | |
| ConsoleColor.Yellow, | |
| ConsoleColor.Black, | |
| String.Format(CultureInfo.CurrentCulture, "WARNING: {0}", message)); | |
| } | |
| public override void WriteProgress(long sourceId, ProgressRecord record) | |
| { | |
| } | |
| private static string[] GetHotkeyAndLabel(string input) | |
| { | |
| string[] result = new string[] { String.Empty, String.Empty }; | |
| string[] fragments = input.Split('&'); | |
| if (fragments.Length == 2) | |
| { | |
| if (fragments[1].Length > 0) | |
| { | |
| result[0] = fragments[1][0].ToString(). | |
| ToUpper(CultureInfo.CurrentCulture); | |
| } | |
| result[1] = (fragments[0] + fragments[1]).Trim(); | |
| } | |
| else | |
| { | |
| result[1] = input; | |
| } | |
| return result; | |
| } | |
| private static string[,] BuildHotkeysAndPlainLabels( | |
| Collection<ChoiceDescription> choices) | |
| { | |
| string[,] hotkeysAndPlainLabels = new string[2, choices.Count]; | |
| for (int i = 0; i < choices.Count; ++i) | |
| { | |
| string[] hotkeyAndLabel = GetHotkeyAndLabel(choices[i].Label); | |
| hotkeysAndPlainLabels[0, i] = hotkeyAndLabel[0]; | |
| hotkeysAndPlainLabels[1, i] = hotkeyAndLabel[1]; | |
| } | |
| return hotkeysAndPlainLabels; | |
| } | |
| } | |
| public class HostUtilities | |
| { | |
| internal const string PowerShellRootKeyPath = "Software\\Microsoft\\PowerShell"; | |
| internal const string PowerShellEngineKey = "PowerShellEngine"; | |
| internal const string PowerShellEngineApplicationBase = "ApplicationBase"; | |
| internal const string RegistryVersionKey = "1"; | |
| internal static PSObject GetDollarProfile(string allUsersAllHosts, string allUsersCurrentHost, string currentUserAllHosts, string currentUserCurrentHost) | |
| { | |
| PSObject returnValue = new PSObject(currentUserCurrentHost); | |
| returnValue.Properties.Add(new PSNoteProperty("AllUsersAllHosts", allUsersAllHosts)); | |
| returnValue.Properties.Add(new PSNoteProperty("AllUsersCurrentHost", allUsersCurrentHost)); | |
| returnValue.Properties.Add(new PSNoteProperty("CurrentUserAllHosts", currentUserAllHosts)); | |
| returnValue.Properties.Add(new PSNoteProperty("CurrentUserCurrentHost", currentUserCurrentHost)); | |
| return returnValue; | |
| } | |
| internal static PSCommand[] GetProfileCommands(string shellId) | |
| { | |
| return HostUtilities.GetProfileCommands(shellId, false); | |
| } | |
| internal static PSCommand[] GetProfileCommands(string shellId, bool useTestProfile) | |
| { | |
| List<PSCommand> commands = new List<PSCommand>(); | |
| string allUsersAllHosts = HostUtilities.GetFullProfileFileName(null, false, useTestProfile); | |
| string allUsersCurrentHost = HostUtilities.GetFullProfileFileName(shellId, false, useTestProfile); | |
| string currentUserAllHosts = HostUtilities.GetFullProfileFileName(null, true, useTestProfile); | |
| string currentUserCurrentHost = HostUtilities.GetFullProfileFileName(shellId, true, useTestProfile); | |
| PSObject dollarProfile = HostUtilities.GetDollarProfile(allUsersAllHosts, allUsersCurrentHost, currentUserAllHosts, currentUserCurrentHost); | |
| PSCommand command = new PSCommand(); | |
| command.AddCommand("set-variable"); | |
| command.AddParameter("Name", "profile"); | |
| command.AddParameter("Value", dollarProfile); | |
| command.AddParameter("Option", ScopedItemOptions.None); | |
| commands.Add(command); | |
| string[] profilePaths = new string[] { allUsersAllHosts, allUsersCurrentHost, currentUserAllHosts, currentUserCurrentHost }; | |
| foreach (string profilePath in profilePaths) | |
| { | |
| if (!System.IO.File.Exists(profilePath)) | |
| { | |
| continue; | |
| } | |
| command = new PSCommand(); | |
| command.AddCommand(profilePath, false); | |
| commands.Add(command); | |
| } | |
| return commands.ToArray(); | |
| } | |
| internal static string GetFullProfileFileName(string shellId, bool forCurrentUser) | |
| { | |
| return HostUtilities.GetFullProfileFileName(shellId, forCurrentUser, false); | |
| } | |
| internal static string GetFullProfileFileName(string shellId, bool forCurrentUser, bool useTestProfile) | |
| { | |
| string basePath = null; | |
| if (forCurrentUser) | |
| { | |
| basePath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); | |
| basePath = System.IO.Path.Combine(basePath, "WindowsPowerShell"); | |
| } | |
| else | |
| { | |
| basePath = GetAllUsersFolderPath(shellId); | |
| if (string.IsNullOrEmpty(basePath)) | |
| { | |
| return string.Empty; | |
| } | |
| } | |
| string profileName = useTestProfile ? "profile_test.ps1" : "profile.ps1"; | |
| if (!string.IsNullOrEmpty(shellId)) | |
| { | |
| profileName = shellId + "_" + profileName; | |
| } | |
| string fullPath = basePath = System.IO.Path.Combine(basePath, profileName); | |
| return fullPath; | |
| } | |
| internal static string GetApplicationBase(string shellId) | |
| { | |
| string engineKeyPath = PowerShellRootKeyPath + "\\" + | |
| RegistryVersionKey + "\\" + PowerShellEngineKey; | |
| using (RegistryKey engineKey = Registry.LocalMachine.OpenSubKey(engineKeyPath)) | |
| { | |
| if (engineKey != null) | |
| { | |
| return engineKey.GetValue(PowerShellEngineApplicationBase) as string; | |
| } | |
| } | |
| Assembly assem = Assembly.GetEntryAssembly(); | |
| if (assem != null) | |
| { | |
| return Path.GetDirectoryName(assem.Location); | |
| } | |
| assem = Assembly.GetAssembly(typeof(System.Management.Automation.PSObject)); | |
| if (assem != null) | |
| { | |
| return Path.GetDirectoryName(assem.Location); | |
| } | |
| return string.Empty; | |
| } | |
| private static string GetAllUsersFolderPath(string shellId) | |
| { | |
| string folderPath = string.Empty; | |
| try | |
| { | |
| folderPath = GetApplicationBase(shellId); | |
| } | |
| catch (System.Security.SecurityException) | |
| { | |
| } | |
| return folderPath; | |
| } | |
| } | |
| internal class MyRawUserInterface : PSHostRawUserInterface | |
| { | |
| public override ConsoleColor BackgroundColor | |
| { | |
| get { return Console.BackgroundColor; } | |
| set { Console.BackgroundColor = value; } | |
| } | |
| public override Size BufferSize | |
| { | |
| get { return new Size(Console.BufferWidth, Console.BufferHeight); } | |
| set { Console.SetBufferSize(value.Width, value.Height); } | |
| } | |
| public override Coordinates CursorPosition | |
| { | |
| get { throw new NotImplementedException("The CursorPosition property is not implemented by MyRawUserInterface."); } | |
| set { throw new NotImplementedException("The CursorPosition property is not implemented by MyRawUserInterface."); } | |
| } | |
| public override int CursorSize | |
| { | |
| get { return Console.CursorSize; } | |
| set { Console.CursorSize = value; } | |
| } | |
| public override ConsoleColor ForegroundColor | |
| { | |
| get { return Console.ForegroundColor; } | |
| set { Console.ForegroundColor = value; } | |
| } | |
| public override bool KeyAvailable | |
| { | |
| get { return Console.KeyAvailable; } | |
| } | |
| public override Size MaxPhysicalWindowSize | |
| { | |
| get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); } | |
| } | |
| public override Size MaxWindowSize | |
| { | |
| get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); } | |
| } | |
| public override Coordinates WindowPosition | |
| { | |
| get { return new Coordinates(Console.WindowLeft, Console.WindowTop); } | |
| set { Console.SetWindowPosition(value.X, value.Y); } | |
| } | |
| public override Size WindowSize | |
| { | |
| get { return new Size(Console.WindowWidth, Console.WindowHeight); } | |
| set { Console.SetWindowSize(value.Width, value.Height); } | |
| } | |
| public override string WindowTitle | |
| { | |
| get { return Console.Title; } | |
| set { Console.Title = value; } | |
| } | |
| public override void FlushInputBuffer() | |
| { | |
| } | |
| public override BufferCell[,] GetBufferContents(Rectangle rectangle) | |
| { | |
| throw new NotImplementedException("The GetBufferContents method is not implemented by MyRawUserInterface."); | |
| } | |
| public override KeyInfo ReadKey(ReadKeyOptions options) | |
| { | |
| throw new NotImplementedException("The ReadKey() method is not implemented by MyRawUserInterface."); | |
| } | |
| public override void ScrollBufferContents(Rectangle source, Coordinates destination, Rectangle clip, BufferCell fill) | |
| { | |
| throw new NotImplementedException("The ScrollBufferContents() method is not implemented by MyRawUserInterface."); | |
| } | |
| public override void SetBufferContents(Coordinates origin, BufferCell[,] contents) | |
| { | |
| throw new NotImplementedException("The SetBufferContents() method is not implemented by MyRawUserInterface."); | |
| } | |
| public override void SetBufferContents(Rectangle rectangle, BufferCell fill) | |
| { | |
| throw new NotImplementedException("The SetBufferContents() method is not implemented by MyRawUserInterface."); | |
| } | |
| } | |
| public static class CredentialUI | |
| { | |
| public static PromptCredentialsResult Prompt(String caption, String message) | |
| { | |
| return Prompt(caption, message, null, null); | |
| } | |
| public static PromptCredentialsResult Prompt(String caption, String message, IntPtr hwndParent) | |
| { | |
| return Prompt(caption, message, hwndParent, null, null); | |
| } | |
| public static PromptCredentialsResult Prompt(String caption, String message, String userName, String password) | |
| { | |
| return Prompt(caption, message, IntPtr.Zero, userName, password); | |
| } | |
| public static PromptCredentialsResult Prompt(String caption, String message, IntPtr hwndParent, String userName, String password) | |
| { | |
| if (Environment.OSVersion.Version.Major >= 6) | |
| { | |
| return PromptForWindowsCredentials(caption, message, hwndParent, userName, password); | |
| } | |
| else | |
| { | |
| return PromptForCredentials(Environment.UserDomainName, caption, message, hwndParent, userName, password); | |
| } | |
| } | |
| public static PromptCredentialsSecureStringResult PromptWithSecureString(String caption, String message) | |
| { | |
| return PromptWithSecureString(caption, message, IntPtr.Zero); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptWithSecureString(String caption, String message, IntPtr hwndParent) | |
| { | |
| return PromptWithSecureString(caption, message, IntPtr.Zero, null, null); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptWithSecureString(String caption, String message, SecureString userName, SecureString password) | |
| { | |
| return PromptWithSecureString(caption, message, IntPtr.Zero, userName, password); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptWithSecureString(String caption, String message, IntPtr hwndParent, SecureString userName, SecureString password) | |
| { | |
| if (Environment.OSVersion.Version.Major >= 6) | |
| { | |
| return PromptForWindowsCredentialsWithSecureString(caption, message, hwndParent, userName, password); | |
| } | |
| else | |
| { | |
| return PromptForCredentialsWithSecureString(Environment.UserDomainName, caption, message, hwndParent, userName, password); | |
| } | |
| } | |
| #region Method: PromptForWindowsCredentials | |
| public static PromptCredentialsResult PromptForWindowsCredentials(String caption, String message) | |
| { | |
| return PromptForWindowsCredentials(caption, message, String.Empty, String.Empty); | |
| } | |
| public static PromptCredentialsResult PromptForWindowsCredentials(String caption, String message, IntPtr hwndParent) | |
| { | |
| return PromptForWindowsCredentials(caption, message, hwndParent); | |
| } | |
| public static PromptCredentialsResult PromptForWindowsCredentials(String caption, String message, String userName, String password) | |
| { | |
| return PromptForWindowsCredentials(caption, message, IntPtr.Zero, userName, password); | |
| } | |
| public static PromptCredentialsResult PromptForWindowsCredentials(String caption, String message, IntPtr hwndParent, String userName, String password) | |
| { | |
| PromptForWindowsCredentialsOptions options = new PromptForWindowsCredentialsOptions(caption, message) | |
| { | |
| HwndParent = hwndParent, | |
| IsSaveChecked = false | |
| }; | |
| return PromptForWindowsCredentials(options, userName, password); | |
| } | |
| public static PromptCredentialsResult PromptForWindowsCredentials(PromptForWindowsCredentialsOptions options, String userName, String password) | |
| { | |
| if (String.IsNullOrEmpty(userName) && String.IsNullOrEmpty(password)) | |
| return PromptForWindowsCredentialsInternal<PromptCredentialsResult>(options, null, null); | |
| using (SecureString userNameS = new SecureString()) | |
| using (SecureString passwordS = new SecureString()) | |
| { | |
| if (!String.IsNullOrEmpty(userName)) | |
| { | |
| foreach (var c in userName) | |
| userNameS.AppendChar(c); | |
| } | |
| if (!String.IsNullOrEmpty(password)) | |
| { | |
| foreach (var c in password) | |
| passwordS.AppendChar(c); | |
| } | |
| userNameS.MakeReadOnly(); | |
| passwordS.MakeReadOnly(); | |
| return PromptForWindowsCredentialsInternal<PromptCredentialsResult>(options, userNameS, passwordS); | |
| } | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForWindowsCredentialsWithSecureString(String caption, String message) | |
| { | |
| return PromptForWindowsCredentialsWithSecureString(caption, message, IntPtr.Zero, null, null); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForWindowsCredentialsWithSecureString(String caption, String message, IntPtr hwndParent) | |
| { | |
| return PromptForWindowsCredentialsWithSecureString(caption, message, hwndParent, null, null); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForWindowsCredentialsWithSecureString(String caption, String message, SecureString userName, SecureString password) | |
| { | |
| return PromptForWindowsCredentialsWithSecureString(caption, message, IntPtr.Zero, userName, password); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForWindowsCredentialsWithSecureString(String caption, String message, IntPtr hwndParent, SecureString userName, SecureString password) | |
| { | |
| PromptForWindowsCredentialsOptions options = new PromptForWindowsCredentialsOptions(caption, message) | |
| { | |
| HwndParent = hwndParent, | |
| IsSaveChecked = false | |
| }; | |
| return PromptForWindowsCredentialsWithSecureString(options, userName, password); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForWindowsCredentialsWithSecureString(PromptForWindowsCredentialsOptions options, SecureString userName, SecureString password) | |
| { | |
| return PromptForWindowsCredentialsInternal<PromptCredentialsSecureStringResult>(options, userName, password); | |
| } | |
| private static T PromptForWindowsCredentialsInternal<T>(PromptForWindowsCredentialsOptions options, SecureString userName, SecureString password) where T : class, IPromptCredentialsResult | |
| { | |
| NativeMethods.CREDUI_INFO creduiInfo = new NativeMethods.CREDUI_INFO() | |
| { | |
| pszCaptionText = options.Caption, | |
| pszMessageText = options.Message, | |
| hwndParent = options.HwndParent, | |
| hbmBanner = options.HbmBanner | |
| }; | |
| PromptForWindowsCredentialsFlag credentialsFlag = options.Flags; | |
| IntPtr userNamePtr = IntPtr.Zero; | |
| IntPtr passwordPtr = IntPtr.Zero; | |
| Int32 authPackage = 0; | |
| IntPtr outAuthBuffer = IntPtr.Zero; | |
| Int32 outAuthBufferSize = 0; | |
| IntPtr inAuthBuffer = IntPtr.Zero; | |
| Int32 inAuthBufferSize = 0; | |
| Boolean save = options.IsSaveChecked; | |
| try | |
| { | |
| if (userName != null || password != null) | |
| { | |
| if (userName == null) | |
| userName = new SecureString(); | |
| if (password == null) | |
| password = new SecureString(); | |
| userNamePtr = Marshal.SecureStringToCoTaskMemUnicode(userName); | |
| passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password); | |
| } | |
| if (userNamePtr != IntPtr.Zero || passwordPtr != IntPtr.Zero) | |
| { | |
| inAuthBufferSize = 1024; | |
| inAuthBuffer = Marshal.AllocCoTaskMem(inAuthBufferSize); | |
| if ( | |
| !NativeMethods.CredPackAuthenticationBuffer(0x00, userNamePtr, passwordPtr, inAuthBuffer, | |
| ref inAuthBufferSize)) | |
| { | |
| var win32Error = Marshal.GetLastWin32Error(); | |
| if (win32Error == 122 /*ERROR_INSUFFICIENT_BUFFER*/) | |
| { | |
| inAuthBuffer = Marshal.ReAllocCoTaskMem(inAuthBuffer, inAuthBufferSize); | |
| if ( | |
| !NativeMethods.CredPackAuthenticationBuffer(0x00, userNamePtr, passwordPtr, inAuthBuffer, | |
| ref inAuthBufferSize)) | |
| { | |
| throw new Win32Exception(Marshal.GetLastWin32Error()); | |
| } | |
| } | |
| else | |
| { | |
| throw new Win32Exception(win32Error); | |
| } | |
| } | |
| } | |
| var retVal = NativeMethods.CredUIPromptForWindowsCredentials(creduiInfo, | |
| options.AuthErrorCode, | |
| ref authPackage, | |
| inAuthBuffer, | |
| inAuthBufferSize, | |
| out outAuthBuffer, | |
| out outAuthBufferSize, | |
| ref save, | |
| credentialsFlag | |
| ); | |
| switch (retVal) | |
| { | |
| case NativeMethods.CredUIPromptReturnCode.Cancelled: | |
| return null; | |
| case NativeMethods.CredUIPromptReturnCode.Success: | |
| break; | |
| default: | |
| throw new Win32Exception((Int32)retVal); | |
| } | |
| if (typeof(T) == typeof(PromptCredentialsSecureStringResult)) | |
| { | |
| var credResult = NativeMethods.CredUnPackAuthenticationBufferWrapSecureString(true, outAuthBuffer, outAuthBufferSize); | |
| credResult.IsSaveChecked = save; | |
| return credResult as T; | |
| } | |
| else | |
| { | |
| var credResult = NativeMethods.CredUnPackAuthenticationBufferWrap(true, outAuthBuffer, outAuthBufferSize); | |
| credResult.IsSaveChecked = save; | |
| return credResult as T; | |
| } | |
| } | |
| finally | |
| { | |
| if (inAuthBuffer != IntPtr.Zero) | |
| Marshal.ZeroFreeCoTaskMemUnicode(inAuthBuffer); | |
| if (outAuthBuffer != IntPtr.Zero) | |
| Marshal.ZeroFreeCoTaskMemUnicode(outAuthBuffer); | |
| if (userNamePtr != IntPtr.Zero) | |
| Marshal.ZeroFreeCoTaskMemUnicode(userNamePtr); | |
| if (passwordPtr != IntPtr.Zero) | |
| Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr); | |
| } | |
| } | |
| #endregion | |
| #region Method: PromptForCredentials | |
| public static PromptCredentialsResult PromptForCredentials(String targetName, String caption, String message) | |
| { | |
| return PromptForCredentials(new PromptForCredentialsOptions(targetName, caption, message)); | |
| } | |
| public static PromptCredentialsResult PromptForCredentials(String targetName, String caption, String message, IntPtr hwndParent) | |
| { | |
| return PromptForCredentials(targetName, caption, message, hwndParent); | |
| } | |
| public static PromptCredentialsResult PromptForCredentials(String targetName, String caption, String message, String userName, String password) | |
| { | |
| return PromptForCredentials(targetName, caption, message, IntPtr.Zero, userName, password); | |
| } | |
| public static PromptCredentialsResult PromptForCredentials(String targetName, String caption, String message, IntPtr hwndParent, String userName, String password) | |
| { | |
| return PromptForCredentials(new PromptForCredentialsOptions(targetName, caption, message) { HwndParent = hwndParent }, userName, password); | |
| } | |
| public static PromptCredentialsResult PromptForCredentials(PromptForCredentialsOptions options) | |
| { | |
| return PromptForCredentials(options, null, null); | |
| } | |
| public static PromptCredentialsResult PromptForCredentials(PromptForCredentialsOptions options, String userName, String password) | |
| { | |
| using (SecureString userNameS = new SecureString()) | |
| using (SecureString passwordS = new SecureString()) | |
| { | |
| if (!String.IsNullOrEmpty(userName)) | |
| { | |
| foreach (var c in userName) | |
| userNameS.AppendChar(c); | |
| } | |
| if (!String.IsNullOrEmpty(password)) | |
| { | |
| foreach (var c in password) | |
| passwordS.AppendChar(c); | |
| } | |
| userNameS.MakeReadOnly(); | |
| passwordS.MakeReadOnly(); | |
| return PromptForCredentialsInternal<PromptCredentialsResult>(options, userNameS, passwordS); | |
| } | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForCredentialsWithSecureString(String targetName, String caption, String message) | |
| { | |
| return PromptForCredentialsWithSecureString(new PromptForCredentialsOptions(targetName, caption, message)); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForCredentialsWithSecureString(String targetName, String caption, String message, IntPtr hwndParent) | |
| { | |
| return PromptForCredentialsWithSecureString(targetName, caption, message, hwndParent, null, null); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForCredentialsWithSecureString(String targetName, String caption, String message, SecureString userName, SecureString password) | |
| { | |
| return PromptForCredentialsWithSecureString(targetName, caption, message, IntPtr.Zero, userName, password); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForCredentialsWithSecureString(String targetName, String caption, String message, IntPtr hwndParent, SecureString userName, SecureString password) | |
| { | |
| return PromptForCredentialsWithSecureString(new PromptForCredentialsOptions(targetName, caption, message) { HwndParent = hwndParent }, userName, password); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForCredentialsWithSecureString(PromptForCredentialsOptions options) | |
| { | |
| return PromptForCredentialsInternal<PromptCredentialsSecureStringResult>(options, null, null); | |
| } | |
| public static PromptCredentialsSecureStringResult PromptForCredentialsWithSecureString(PromptForCredentialsOptions options, SecureString userName, SecureString password) | |
| { | |
| return PromptForCredentialsInternal<PromptCredentialsSecureStringResult>(options, userName, password); | |
| } | |
| private static T PromptForCredentialsInternal<T>(PromptForCredentialsOptions options, SecureString userName, SecureString password) where T : class, IPromptCredentialsResult | |
| { | |
| if (options == null) | |
| throw new ArgumentNullException("options"); | |
| if (userName != null && (userName.Length > NativeMethods.CREDUI_MAX_USERNAME_LENGTH)) | |
| throw new ArgumentOutOfRangeException("userName", "CREDUI_MAX_USERNAME_LENGTH"); | |
| if (password != null && (password.Length > NativeMethods.CREDUI_MAX_PASSWORD_LENGTH)) | |
| throw new ArgumentOutOfRangeException("password", "CREDUI_MAX_PASSWORD_LENGTH"); | |
| NativeMethods.CREDUI_INFO creduiInfo = new NativeMethods.CREDUI_INFO() | |
| { | |
| pszCaptionText = options.Caption, | |
| pszMessageText = options.Message, | |
| hwndParent = options.HwndParent, | |
| hbmBanner = options.HbmBanner | |
| }; | |
| IntPtr userNamePtr = IntPtr.Zero; | |
| IntPtr passwordPtr = IntPtr.Zero; | |
| Boolean save = options.IsSaveChecked; | |
| try | |
| { | |
| if (userName == null) | |
| { | |
| userNamePtr = Marshal.AllocCoTaskMem((NativeMethods.CREDUI_MAX_USERNAME_LENGTH + 1) * sizeof(Int16)); | |
| Marshal.WriteInt16(userNamePtr, 0, 0x00); | |
| } | |
| else | |
| { | |
| userNamePtr = Marshal.SecureStringToCoTaskMemUnicode(userName); | |
| userNamePtr = Marshal.ReAllocCoTaskMem(userNamePtr, (NativeMethods.CREDUI_MAX_USERNAME_LENGTH + 1) * sizeof(Int16)); | |
| } | |
| if (password == null) | |
| { | |
| passwordPtr = Marshal.AllocCoTaskMem((NativeMethods.CREDUI_MAX_PASSWORD_LENGTH + 1) * sizeof(Int16)); | |
| Marshal.WriteInt16(passwordPtr, 0, 0x00); | |
| } | |
| else | |
| { | |
| passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password); | |
| passwordPtr = Marshal.ReAllocCoTaskMem(passwordPtr, (NativeMethods.CREDUI_MAX_PASSWORD_LENGTH + 1) * sizeof(Int16)); | |
| } | |
| Marshal.WriteInt16(userNamePtr, NativeMethods.CREDUI_MAX_USERNAME_LENGTH * sizeof(Int16), 0x00); | |
| Marshal.WriteInt16(passwordPtr, NativeMethods.CREDUI_MAX_PASSWORD_LENGTH * sizeof(Int16), 0x00); | |
| var retVal = NativeMethods.CredUIPromptForCredentials(creduiInfo, | |
| options.TargetName, | |
| IntPtr.Zero, | |
| options.AuthErrorCode, | |
| userNamePtr, | |
| NativeMethods.CREDUI_MAX_USERNAME_LENGTH, | |
| passwordPtr, | |
| NativeMethods.CREDUI_MAX_PASSWORD_LENGTH, | |
| ref save, | |
| options.Flags); | |
| switch (retVal) | |
| { | |
| case NativeMethods.CredUIPromptReturnCode.Cancelled: | |
| return null; | |
| case NativeMethods.CredUIPromptReturnCode.InvalidParameter: | |
| throw new Win32Exception((Int32)retVal); | |
| case NativeMethods.CredUIPromptReturnCode.InvalidFlags: | |
| throw new Win32Exception((Int32)retVal); | |
| case NativeMethods.CredUIPromptReturnCode.Success: | |
| break; | |
| default: | |
| throw new Win32Exception((Int32)retVal); | |
| } | |
| if (typeof(T) == typeof(PromptCredentialsSecureStringResult)) | |
| { | |
| return new PromptCredentialsSecureStringResult | |
| { | |
| UserName = NativeMethods.PtrToSecureString(userNamePtr), | |
| Password = NativeMethods.PtrToSecureString(passwordPtr), | |
| IsSaveChecked = save | |
| } as T; | |
| } | |
| else | |
| { | |
| return new PromptCredentialsResult | |
| { | |
| UserName = Marshal.PtrToStringUni(userNamePtr), | |
| Password = Marshal.PtrToStringUni(passwordPtr), | |
| IsSaveChecked = save | |
| } as T; | |
| } | |
| } | |
| finally | |
| { | |
| if (userNamePtr != IntPtr.Zero) | |
| Marshal.ZeroFreeCoTaskMemUnicode(userNamePtr); | |
| if (passwordPtr != IntPtr.Zero) | |
| Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr); | |
| } | |
| } | |
| #endregion | |
| [Flags] | |
| public enum PromptForWindowsCredentialsFlag | |
| { | |
| CREDUIWIN_GENERIC = 0x00000001, | |
| CREDUIWIN_CHECKBOX = 0x00000002, | |
| CREDUIWIN_AUTHPACKAGE_ONLY = 0x00000010, | |
| CREDUIWIN_IN_CRED_ONLY = 0x00000020, | |
| CREDUIWIN_ENUMERATE_ADMINS = 0x00000100, | |
| CREDUIWIN_ENUMERATE_CURRENT_USER = 0x00000200, | |
| CREDUIWIN_SECURE_PROMPT = 0x00001000, | |
| CREDUIWIN_PACK_32_WOW = 0x10000000 | |
| } | |
| [Flags] | |
| public enum PromptForCredentialsFlag | |
| { | |
| CREDUI_FLAGS_INCORRECT_PASSWORD = 0x00001, | |
| CREDUI_FLAGS_DO_NOT_PERSIST = 0x00002, | |
| CREDUI_FLAGS_REQUEST_ADMINISTRATOR = 0x00004, | |
| CREDUI_FLAGS_EXCLUDE_CERTIFICATES = 0x00008, | |
| CREDUI_FLAGS_REQUIRE_CERTIFICATE = 0x00010, | |
| CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX = 0x00040, | |
| CREDUI_FLAGS_ALWAYS_SHOW_UI = 0x00080, | |
| CREDUI_FLAGS_REQUIRE_SMARTCARD = 0x00100, | |
| CREDUI_FLAGS_PASSWORD_ONLY_OK = 0x00200, | |
| CREDUI_FLAGS_VALIDATE_USERNAME = 0x00400, | |
| CREDUI_FLAGS_COMPLETE_USERNAME = 0x00800, | |
| CREDUI_FLAGS_PERSIST = 0x01000, | |
| CREDUI_FLAGS_SERVER_CREDENTIAL = 0x04000, | |
| CREDUI_FLAGS_EXPECT_CONFIRMATION = 0x20000, | |
| CREDUI_FLAGS_GENERIC_CREDENTIALS = 0x40000, | |
| CREDUI_FLAGS_USERNAME_TARGET_CREDENTIALS = 0x80000, | |
| CREDUI_FLAGS_KEEP_USERNAME = 0x100000 | |
| } | |
| public class PromptForWindowsCredentialsOptions | |
| { | |
| private String _caption; | |
| private String _message; | |
| public String Caption | |
| { | |
| get { return _caption; } | |
| set | |
| { | |
| if (value.Length > NativeMethods.CREDUI_MAX_CAPTION_LENGTH) | |
| throw new ArgumentOutOfRangeException("value"); | |
| _caption = value; | |
| } | |
| } | |
| public String Message | |
| { | |
| get { return _message; } | |
| set | |
| { | |
| if (value.Length > NativeMethods.CREDUI_MAX_MESSAGE_LENGTH) | |
| throw new ArgumentOutOfRangeException("value"); | |
| _message = value; | |
| } | |
| } | |
| public IntPtr HwndParent { get; set; } | |
| public IntPtr HbmBanner { get; set; } | |
| public Boolean IsSaveChecked { get; set; } | |
| public PromptForWindowsCredentialsFlag Flags { get; set; } | |
| public Int32 AuthErrorCode { get; set; } | |
| public PromptForWindowsCredentialsOptions(String caption, String message) | |
| { | |
| if (String.IsNullOrEmpty(caption)) | |
| throw new ArgumentNullException("caption"); | |
| if (String.IsNullOrEmpty(message)) | |
| throw new ArgumentNullException("message"); | |
| Caption = caption; | |
| Message = message; | |
| Flags = PromptForWindowsCredentialsFlag.CREDUIWIN_GENERIC; | |
| } | |
| } | |
| public class PromptForCredentialsOptions | |
| { | |
| private String _caption; | |
| private String _message; | |
| public String Caption | |
| { | |
| get { return _caption; } | |
| set | |
| { | |
| if (value.Length > NativeMethods.CREDUI_MAX_CAPTION_LENGTH) | |
| throw new ArgumentOutOfRangeException("value"); | |
| _caption = value; | |
| } | |
| } | |
| public String Message | |
| { | |
| get { return _message; } | |
| set | |
| { | |
| if (value.Length > NativeMethods.CREDUI_MAX_MESSAGE_LENGTH) | |
| throw new ArgumentOutOfRangeException("value"); | |
| _message = value; | |
| } | |
| } | |
| public String TargetName { get; set; } | |
| public IntPtr HwndParent { get; set; } | |
| public IntPtr HbmBanner { get; set; } | |
| public Boolean IsSaveChecked { get; set; } | |
| public PromptForCredentialsFlag Flags { get; set; } | |
| public Int32 AuthErrorCode { get; set; } | |
| public PromptForCredentialsOptions(String targetName, String caption, String message) | |
| { | |
| if (String.IsNullOrEmpty(caption)) | |
| throw new ArgumentNullException("caption"); | |
| if (String.IsNullOrEmpty(message)) | |
| throw new ArgumentNullException("message"); | |
| TargetName = targetName; | |
| Caption = caption; | |
| Message = message; | |
| Flags = PromptForCredentialsFlag.CREDUI_FLAGS_GENERIC_CREDENTIALS | PromptForCredentialsFlag.CREDUI_FLAGS_DO_NOT_PERSIST; | |
| } | |
| } | |
| private static class NativeMethods | |
| { | |
| public const Int32 CREDUI_MAX_MESSAGE_LENGTH = 32767; | |
| public const Int32 CREDUI_MAX_CAPTION_LENGTH = 128; | |
| public const Int32 CRED_MAX_USERNAME_LENGTH = (256 + 1 + 256); | |
| public const Int32 CREDUI_MAX_USERNAME_LENGTH = CRED_MAX_USERNAME_LENGTH; | |
| public const Int32 CREDUI_MAX_PASSWORD_LENGTH = (512 / 2); | |
| public enum CredUIPromptReturnCode | |
| { | |
| Success = 0, | |
| Cancelled = 1223, | |
| InvalidParameter = 87, | |
| InvalidFlags = 1004 | |
| } | |
| [StructLayout(LayoutKind.Sequential)] | |
| public class CREDUI_INFO | |
| { | |
| public Int32 cbSize; | |
| public IntPtr hwndParent; | |
| [MarshalAs(UnmanagedType.LPWStr)] | |
| public String pszMessageText; | |
| [MarshalAs(UnmanagedType.LPWStr)] | |
| public String pszCaptionText; | |
| public IntPtr hbmBanner; | |
| public CREDUI_INFO() | |
| { | |
| cbSize = Marshal.SizeOf(typeof(CREDUI_INFO)); | |
| } | |
| } | |
| // | |
| // | |
| [DllImport("credui.dll", CharSet = CharSet.Unicode)] | |
| public static extern CredUIPromptReturnCode CredUIPromptForCredentials( | |
| CREDUI_INFO pUiInfo, | |
| String pszTargetName, | |
| IntPtr Reserved, | |
| Int32 dwAuthError, | |
| IntPtr pszUserName, | |
| Int32 ulUserNameMaxChars, | |
| IntPtr pszPassword, | |
| Int32 ulPasswordMaxChars, | |
| ref Boolean pfSave, | |
| PromptForCredentialsFlag dwFlags | |
| ); | |
| // | |
| // | |
| [DllImport("credui.dll", CharSet = CharSet.Unicode)] | |
| public static extern CredUIPromptReturnCode | |
| CredUIPromptForWindowsCredentials( | |
| CREDUI_INFO pUiInfo, | |
| Int32 dwAuthError, | |
| ref Int32 pulAuthPackage, | |
| IntPtr pvInAuthBuffer, | |
| Int32 ulInAuthBufferSize, | |
| out IntPtr ppvOutAuthBuffer, | |
| out Int32 pulOutAuthBufferSize, | |
| ref Boolean pfSave, | |
| PromptForWindowsCredentialsFlag dwFlags | |
| ); | |
| [DllImport("credui.dll", CharSet = CharSet.Unicode, SetLastError = true)] | |
| public static extern Boolean CredPackAuthenticationBuffer( | |
| Int32 dwFlags, | |
| String pszUserName, | |
| String pszPassword, | |
| IntPtr pPackedCredentials, | |
| ref Int32 pcbPackedCredentials | |
| ); | |
| [DllImport("credui.dll", CharSet = CharSet.Unicode, SetLastError = true)] | |
| public static extern Boolean CredPackAuthenticationBuffer( | |
| Int32 dwFlags, | |
| IntPtr pszUserName, | |
| IntPtr pszPassword, | |
| IntPtr pPackedCredentials, | |
| ref Int32 pcbPackedCredentials | |
| ); | |
| [DllImport("credui.dll", CharSet = CharSet.Unicode, SetLastError = true)] | |
| public static extern Boolean CredUnPackAuthenticationBuffer( | |
| Int32 dwFlags, | |
| IntPtr pAuthBuffer, | |
| Int32 cbAuthBuffer, | |
| StringBuilder pszUserName, | |
| ref Int32 pcchMaxUserName, | |
| StringBuilder pszDomainName, | |
| ref Int32 pcchMaxDomainame, | |
| StringBuilder pszPassword, | |
| ref Int32 pcchMaxPassword | |
| ); | |
| [DllImport("credui.dll", CharSet = CharSet.Unicode, SetLastError = true)] | |
| public static extern Boolean CredUnPackAuthenticationBuffer( | |
| Int32 dwFlags, | |
| IntPtr pAuthBuffer, | |
| Int32 cbAuthBuffer, | |
| IntPtr pszUserName, | |
| ref Int32 pcchMaxUserName, | |
| IntPtr pszDomainName, | |
| ref Int32 pcchMaxDomainame, | |
| IntPtr pszPassword, | |
| ref Int32 pcchMaxPassword | |
| ); | |
| public static PromptCredentialsResult CredUnPackAuthenticationBufferWrap(Boolean decryptProtectedCredentials, IntPtr authBufferPtr, Int32 authBufferSize) | |
| { | |
| StringBuilder sbUserName = new StringBuilder(255); | |
| StringBuilder sbDomainName = new StringBuilder(255); | |
| StringBuilder sbPassword = new StringBuilder(255); | |
| Int32 userNameSize = sbUserName.Capacity; | |
| Int32 domainNameSize = sbDomainName.Capacity; | |
| Int32 passwordSize = sbPassword.Capacity; | |
| //#define CRED_PACK_PROTECTED_CREDENTIALS 0x1 | |
| //#define CRED_PACK_WOW_BUFFER 0x2 | |
| //#define CRED_PACK_GENERIC_CREDENTIALS 0x4 | |
| Boolean result = CredUnPackAuthenticationBuffer((decryptProtectedCredentials ? 0x1 : 0x0), | |
| authBufferPtr, | |
| authBufferSize, | |
| sbUserName, | |
| ref userNameSize, | |
| sbDomainName, | |
| ref domainNameSize, | |
| sbPassword, | |
| ref passwordSize | |
| ); | |
| if (!result) | |
| { | |
| var win32Error = Marshal.GetLastWin32Error(); | |
| if (win32Error == 122 /*ERROR_INSUFFICIENT_BUFFER*/) | |
| { | |
| sbUserName.Capacity = userNameSize; | |
| sbPassword.Capacity = passwordSize; | |
| sbDomainName.Capacity = domainNameSize; | |
| result = CredUnPackAuthenticationBuffer((decryptProtectedCredentials ? 0x1 : 0x0), | |
| authBufferPtr, | |
| authBufferSize, | |
| sbUserName, | |
| ref userNameSize, | |
| sbDomainName, | |
| ref domainNameSize, | |
| sbPassword, | |
| ref passwordSize | |
| ); | |
| if (!result) | |
| { | |
| throw new Win32Exception(Marshal.GetLastWin32Error()); | |
| } | |
| } | |
| else | |
| { | |
| throw new Win32Exception(win32Error); | |
| } | |
| } | |
| return new PromptCredentialsResult | |
| { | |
| UserName = sbUserName.ToString(), | |
| DomainName = sbDomainName.ToString(), | |
| Password = sbPassword.ToString() | |
| }; | |
| } | |
| public static PromptCredentialsSecureStringResult CredUnPackAuthenticationBufferWrapSecureString(Boolean decryptProtectedCredentials, IntPtr authBufferPtr, Int32 authBufferSize) | |
| { | |
| Int32 userNameSize = 255; | |
| Int32 domainNameSize = 255; | |
| Int32 passwordSize = 255; | |
| IntPtr userNamePtr = IntPtr.Zero; | |
| IntPtr domainNamePtr = IntPtr.Zero; | |
| IntPtr passwordPtr = IntPtr.Zero; | |
| try | |
| { | |
| userNamePtr = Marshal.AllocCoTaskMem(userNameSize); | |
| domainNamePtr = Marshal.AllocCoTaskMem(domainNameSize); | |
| passwordPtr = Marshal.AllocCoTaskMem(passwordSize); | |
| //#define CRED_PACK_PROTECTED_CREDENTIALS 0x1 | |
| //#define CRED_PACK_WOW_BUFFER 0x2 | |
| //#define CRED_PACK_GENERIC_CREDENTIALS 0x4 | |
| Boolean result = CredUnPackAuthenticationBuffer((decryptProtectedCredentials ? 0x1 : 0x0), | |
| authBufferPtr, | |
| authBufferSize, | |
| userNamePtr, | |
| ref userNameSize, | |
| domainNamePtr, | |
| ref domainNameSize, | |
| passwordPtr, | |
| ref passwordSize | |
| ); | |
| if (!result) | |
| { | |
| var win32Error = Marshal.GetLastWin32Error(); | |
| if (win32Error == 122 /*ERROR_INSUFFICIENT_BUFFER*/) | |
| { | |
| userNamePtr = Marshal.ReAllocCoTaskMem(userNamePtr, userNameSize); | |
| domainNamePtr = Marshal.ReAllocCoTaskMem(domainNamePtr, domainNameSize); | |
| passwordPtr = Marshal.ReAllocCoTaskMem(passwordPtr, passwordSize); | |
| result = CredUnPackAuthenticationBuffer((decryptProtectedCredentials ? 0x1 : 0x0), | |
| authBufferPtr, | |
| authBufferSize, | |
| userNamePtr, | |
| ref userNameSize, | |
| domainNamePtr, | |
| ref domainNameSize, | |
| passwordPtr, | |
| ref passwordSize); | |
| if (!result) | |
| { | |
| throw new Win32Exception(Marshal.GetLastWin32Error()); | |
| } | |
| } | |
| else | |
| { | |
| throw new Win32Exception(win32Error); | |
| } | |
| } | |
| return new PromptCredentialsSecureStringResult | |
| { | |
| UserName = PtrToSecureString(userNamePtr, userNameSize), | |
| DomainName = PtrToSecureString(domainNamePtr, domainNameSize), | |
| Password = PtrToSecureString(passwordPtr, passwordSize) | |
| }; | |
| } | |
| finally | |
| { | |
| if (userNamePtr != IntPtr.Zero) | |
| Marshal.ZeroFreeCoTaskMemUnicode(userNamePtr); | |
| if (domainNamePtr != IntPtr.Zero) | |
| Marshal.ZeroFreeCoTaskMemUnicode(domainNamePtr); | |
| if (passwordPtr != IntPtr.Zero) | |
| Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr); | |
| } | |
| } | |
| #region Utility Methods | |
| public static SecureString PtrToSecureString(IntPtr p) | |
| { | |
| SecureString s = new SecureString(); | |
| Int32 i = 0; | |
| while (true) | |
| { | |
| Char c = (Char)Marshal.ReadInt16(p, ((i++) * sizeof(Int16))); | |
| if (c == '\u0000') | |
| break; | |
| s.AppendChar(c); | |
| } | |
| s.MakeReadOnly(); | |
| return s; | |
| } | |
| public static SecureString PtrToSecureString(IntPtr p, Int32 length) | |
| { | |
| SecureString s = new SecureString(); | |
| for (var i = 0; i < length; i++) | |
| s.AppendChar((Char)Marshal.ReadInt16(p, i * sizeof(Int16))); | |
| s.MakeReadOnly(); | |
| return s; | |
| } | |
| #endregion | |
| } | |
| } | |
| public interface IPromptCredentialsResult | |
| { | |
| } | |
| public class PromptCredentialsResult : IPromptCredentialsResult | |
| { | |
| public String UserName { get; internal set; } | |
| public String DomainName { get; internal set; } | |
| public String Password { get; internal set; } | |
| public Boolean IsSaveChecked { get; set; } | |
| } | |
| public class PromptCredentialsSecureStringResult : IPromptCredentialsResult | |
| { | |
| public SecureString UserName { get; internal set; } | |
| public SecureString DomainName { get; internal set; } | |
| public SecureString Password { get; internal set; } | |
| public Boolean IsSaveChecked { get; set; } | |
| } | |
| public static class ExtensionMethods | |
| { | |
| public static SecureString ToSecureString(this string src) | |
| { | |
| SecureString result = new SecureString(); | |
| src.ToCharArray().ToList().ForEach(c => result.AppendChar(c)); | |
| return result; | |
| } | |
| } | |
| ]]> | |
| </Code> | |
| </Task> | |
| </UsingTask> | |
| </Project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment