[英]Custom PSHost, Get-Credential cmdlet in C#
i am trying to implement a custom PSHost class for the purpose of crafting GUIs for Power Shell scripts. 我试图实现自定义PSHost类,以便为Power Shell脚本制作GUI。 I have taken the code here as a base and started adapting it for GUI Projects https://msdn.microsoft.com/en-us/library/ee706557%28v=vs.85%29.aspx
我已将此处的代码作为基础,并开始对其进行调整以适合GUI项目https://msdn.microsoft.com/en-us/library/ee706557%28v=vs.85%29.aspx
All was fine until i tried to run the Get-Credential cmdlet and got a error that the method is not implemented(ooouuuu)... The initial code was these two methods: 一切都很好,直到我尝试运行Get-Credential cmdlet并收到未实现该方法的错误(ooouuuu)...初始代码是这两种方法:
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName)
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName,
PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options)
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
So after some research i implemented the dialogue like this: 因此,经过一些研究,我实现了这样的对话:
[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 enum PromptForWindowsCredentialsFlags
{
...
}
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName,
PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options)
{
CREDUI_INFO credui = new CREDUI_INFO();
credui.pszCaptionText = "Please enter the credentails";
credui.pszMessageText = "DisplayedMessage";
credui.cbSize = Marshal.SizeOf(credui);
uint authPackage = 0;
IntPtr outCredBuffer = new IntPtr();
uint outCredSize;
bool save = false;
int result = CredUIPromptForWindowsCredentials(ref credui, 0, ref authPackage, IntPtr.Zero, 0, out outCredBuffer, out outCredSize, ref save, 1 /* Generic */);
var usernameBuf = new StringBuilder(100);
var passwordBuf = new StringBuilder(100);
var domainBuf = new StringBuilder(100);
int maxUserName = 100;
int maxDomain = 100;
int maxPassword = 100;
if (result == 0)
{
if (CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredSize, usernameBuf, ref maxUserName, domainBuf, ref maxDomain, passwordBuf, ref maxPassword))
{
//clear the memory allocated by CredUIPromptForWindowsCredentials
CoTaskMemFree(outCredBuffer);
SecureString secureString = new SecureString();
foreach (char c in passwordBuf.ToString())
{
secureString.AppendChar(c);
}
return new PSCredential(usernameBuf.ToString(), secureString);
}
}
return null;
}
This works fine but there is one snag, when running the Get-Credential cmdlet it prompts for a value for the Credential parameter, regardless of any input after hitting return the dialogue pops up and everything works as expected. 这可以正常工作,但存在一个障碍,运行Get-Credential cmdlet时,它将提示输入Credential参数的值,无论在按回车键后输入任何内容,都会弹出对话框,并且一切都按预期进行。 Doing the same in ISE the dialogue pops up directly without any prompt.
在ISE中执行相同操作,对话框将直接弹出,而没有任何提示。 I thought it was due to the arguments of the method but making them optional by defining a default value did not make a difference.
我认为这是由于该方法的参数所致,但是通过定义默认值使它们成为可选参数并没有什么不同。 It might be due to how the cmdlet is defined in the PS environment so my question is: How can i make it so that running the cmdlet will jump straight to the dialogue?
这可能是由于在PS环境中如何定义cmdlet,所以我的问题是:我该如何做到这一点,以便运行cmdlet可以直接跳至对话? Is it possible to define a default value for the Credential parameter to bind to?
是否可以为要绑定到的Credential参数定义默认值? I'm guessing this is how ISE gets around this or am i missing something?
我猜这是ISE如何解决这个问题或我缺少什么吗?
我花了一些时间进行试验,但是我发现,强制参数绑定由PSHostUserInterface接口中的public override Dictionary<string, PSObject> Prompt(string caption, string message, Collection<FieldDescription> descriptions)
方法处理,然后PromptForCredential
调用PromptForCredential
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.