65.9K
CodeProject 正在变化。 阅读更多。
Home

用于 PowerShell 的自定义 C# 控件

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2012年1月7日

CPOL

2分钟阅读

viewsIcon

29665

downloadIcon

640

用于 PowerShell New-PSDrive cmdlet 的可自定义的自定义 C# 控件

image001.jpg

引言

PowerShell 包含直接访问 .NET 的能力,并且 C# 可以直接集成。在这个项目中,创建了一个自定义 C# 控件,并直接从 PowerShell 访问它,以增强 New-PSDrive cmdlet 的功能。一旦创建了具有适当子控件的控件,就可以通过命名空间和类名从 PowerShell 访问它(请参阅包含的 PowerShell 脚本以访问该控件)。这是一个创建控件并从 PowerShell 访问它的简单示例。

PowerShell 包含访问 Windows Presentation Foundations 命名空间的权限,并在 PowerShell 脚本中使用它来创建托管自定义 C# 控件的父窗体。在这个例子中,自定义控件使用反射加载,但在 PowerShell 3 中,也可以使用 Add-Type cmdlet 加载程序集。

namespace PSMap
{
    partial class MapControl
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; 
        /// otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.DriveLetter = new System.Windows.Forms.ComboBox();
            this.ServerName = new System.Windows.Forms.ComboBox();
            this.ShareName = new System.Windows.Forms.ComboBox();
            this.Credentials = new System.Windows.Forms.ComboBox();
            this.lb_DriveLetter = new System.Windows.Forms.Label();
            this.lb_ServerName = new System.Windows.Forms.Label();
            this.lb_ShareName = new System.Windows.Forms.Label();
            this.lb_Credentials = new System.Windows.Forms.Label();
            this.lb_Title = new System.Windows.Forms.Label();
            this.lb_justcode = new System.Windows.Forms.Label();
            this.lb_About_PSMap = new System.Windows.Forms.Label();
            this.PSProvider = new System.Windows.Forms.ComboBox();
            this.lb_psprovider = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // DriveLetter
            // 
            this.DriveLetter.FormattingEnabled = true;
            this.DriveLetter.Items.AddRange(new object[] {
            "HKLM",
            "G",
            "H",
            "I",
            "J",
            "K",
            "L",
            "M",
            "N",
            "O",
            "P",
            "Q",
            "R",
            "S",
            "T",
            "U",
            "V",
            "W",
            "X",
            "Y",
            "Z"});
            this.DriveLetter.Location = new System.Drawing.Point(6, 54);
            this.DriveLetter.Name = "DriveLetter";
            this.DriveLetter.Size = new System.Drawing.Size(96, 21);
            this.DriveLetter.TabIndex = 0;
            this.DriveLetter.SelectedIndexChanged += 
		new System.EventHandler(this.DriveLetter_SelectedIndexChanged);
            // 
            // ServerName
            // 
            
	     // … ( see included project )   
        }

        #endregion

        private System.Windows.Forms.ComboBox DriveLetter;
        private System.Windows.Forms.ComboBox ServerName;
        private System.Windows.Forms.ComboBox ShareName;
        private System.Windows.Forms.ComboBox Credentials;
        private System.Windows.Forms.Label lb_DriveLetter;
        private System.Windows.Forms.Label lb_ServerName;
        private System.Windows.Forms.Label lb_ShareName;
        private System.Windows.Forms.Label lb_Credentials;
        private System.Windows.Forms.Label lb_Title;
        private System.Windows.Forms.Label lb_justcode;
        private System.Windows.Forms.Label lb_About_PSMap;
        private System.Windows.Forms.ComboBox PSProvider;
        private System.Windows.Forms.Label lb_psprovider;
    }
}

在 Visual Studio 2010 中,您可以创建一个新的项目“Windows Forms 控件库”来创建自定义窗体控件。

image002.jpg

您还需要将您的 .NET 版本设置为合适的版本。 在这种情况下,我选择了 .NET Framework 3.5。

您还需要为您的程序集生成强名称。 部署包中包含一个批处理文件 (PSMapDll-Deploy.zip),可用于生成强名称。

这个可定制的 PowerShell 自定义控件允许您轻松输入 New-PSDrive cmdlet 的参数。只需运行以下脚本。我计划为其创建一个模块。

重要提示:您必须设置正确的 PowerShell 执行策略 *并且* 您必须取消阻止 PSMap.dll 文件 (C:\PSMapDll-Deploy\PSMap.dll – 点击属性 -> 取消阻止)。以下是完整的 PowerShell 包的链接。

PSMapDll-Deploy

以下是包含的示例 PowerShell 脚本,用于运行自定义控件(将包提取到 C: 或创建 PSMapDll-Deploy 目录并在那里提取文件)。 如果由于任何原因,您在 PowerShell 脚本中加载 DLL 时遇到任何问题,可以使用 inst-gac.bat 文件将程序集安装到您的全局程序集缓存中。uninst-gac.bat 也包含在内。 上面的下载包中也包含以下 PowerShell 脚本。

该脚本将在您单击确定后连接您在自定义控件中指定的驱动器。 如果输入了凭据,它将使用这些凭据,但是对于正常操作不需要替代凭据(因此在这种情况下请将该字段留空)。

# load the customizable custom control
[Reflection.Assembly]::LoadFile('C:\PSMapDll-Deploy\PSMap.dll')  
 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
 
# Setup the main forms
$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "PSMapForm"
$objForm.Size = New-Object System.Drawing.Size(600,340) 
$objForm.StartPosition = "CenterScreen"
# add the PSMap custom control
$objCustom = New-Object PSMap.MapControl
$objCustom.Location = New-Object System.Drawing.Size(0,0)
$objCustom.Size = New-Object System.Drawing.Size(600,300)
 
#  add items as needed to the customize the controls of the PSMap custom control
$t = $objCustom.Controls.Item("ServerName")
$t.Items.Add("TestServer1")
$t.Items.Add("TestServer2")
 
$t = $objCustom.Controls.Item("ShareName")
$t.Items.Add("C$")
$t.Items.Add("MyShare")
 
$t = $objCustom.Controls.Item("Credentials")
$t.Items.Add("Computername\Username")
$t.Items.Add("DomainName\Username")
 
$t = $objCustom.Controls.Item("PSProvider")
$t.Items.Add("testprovider")
 
$t = $objCustom.Controls.Item("Credentials")
$t.Items.Add("domain\username")
 
#Add main form functionality and run form
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(500,260)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$y = $objCustom;$objForm.Close()})
$objForm.Controls.Add($OKButton)$objForm.Controls.Add($objCustom)
$objForm.Topmost = $True
[void] $objForm.ShowDialog()
 
# create the UNC path variable from entered items
$z = "\\" + $y.Controls.Item("ServerName").Text + "\" + $y.Controls.Item("ShareName").Text
# create a test variable to test the credentials item
$x = $y.Controls.Item("Credentials")
# write out variables retrieved as an example for this sample script
$z$y.Controls.Item("DriveLetter").Text
$y.Controls.Item("Credentials").Text
 $y.Controls.Item("PSProvider").Text
$y.Controls.Item("ServerName").Text
$y.Controls.Item("ShareName").Text
$x.Text
 
# test the credentials variable and call the correct map command 
based on whether its present
if($x.Text -eq "") { 
 New-PSDrive -Name $y.Controls.Item("DriveLetter").Text 
 -PSProvider $y.Controls.Item("PSProvider").Text -Root $z
}
Else { 
 New-PSDrive -Name $y.Controls.Item("DriveLetter").Text 
 -PSProvider $y.Controls.Item("PSProvider").Text -Root $z -Credential $x.Text
}

历史

  • 2012 年 1 月 7 日:初始版本
© . All rights reserved.