Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 自定义PSHost,在C中获取凭据cmdlet#_C#_Pshost - Fatal编程技术网

C# 自定义PSHost,在C中获取凭据cmdlet#

C# 自定义PSHost,在C中获取凭据cmdlet#,c#,pshost,C#,Pshost,我试图实现一个定制的PSHost类,以便为powershell脚本制作gui。 我将这里的代码作为基础,并开始将其用于GUI项目 一切都很好,直到我尝试运行Get-Credential cmdlet并得到一个错误,该方法未实现(oouuuu)。。。 最初的代码是这两种方法: public override PSCredential PromptForCredential( string capti

我试图实现一个定制的PSHost类,以便为powershell脚本制作gui。 我将这里的代码作为基础,并开始将其用于GUI项目

一切都很好,直到我尝试运行Get-Credential cmdlet并得到一个错误,该方法未实现(oouuuu)。。。 最初的代码是这两种方法:

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.");
}
因此,经过一些研究,我实施了如下对话:

    [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;
    }
这可以正常工作,但有一个障碍,当运行Get-Credential cmdlet时,它会提示输入Credential参数的值,而不管在点击return之后有什么输入,都会弹出对话框,并且一切正常。 在ISE中执行相同操作时,对话会直接弹出,没有任何提示。 我认为这是由于方法的参数,但是通过定义默认值使它们成为可选的并没有什么区别。 这可能是由于在PS环境中如何定义cmdlet造成的,因此我的问题是: 如何使运行cmdlet直接跳转到对话?
是否可以为要绑定的凭据参数定义默认值?我猜这就是ISE解决这个问题的方法,还是我遗漏了什么?

我花了一些时间进行实验,但我发现了它,强制参数绑定由
公共覆盖字典提示(字符串标题、字符串消息、集合描述)处理调用
PromptForCredential
之前,在PSHostUserInterface界面中的方法