用于 PowerShell 的自定义 C# 控件





5.00/5 (1投票)
用于 PowerShell New-PSDrive cmdlet 的可自定义的自定义 C# 控件

引言
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 控件库”来创建自定义窗体控件。

您还需要将您的 .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 日:初始版本