C# Powershell:无法与存储在.Net程序集中的表单交互
我只是想学习这个东西,将来想在我的一个项目中使用它 我有一个带有简单文本框的小表单,存储在.NETDLL(C#)中。这是我在这个dll中的类,它包含与这个表单交互的方法:C# Powershell:无法与存储在.Net程序集中的表单交互,c#,winforms,powershell,C#,Winforms,Powershell,我只是想学习这个东西,将来想在我的一个项目中使用它 我有一个带有简单文本框的小表单,存储在.NETDLL(C#)中。这是我在这个dll中的类,它包含与这个表单交互的方法: using System; using System.Collections.Generic; using System.Text; namespace ClassLibrary1 { public class Class1 { static Form1 dlg = new Form1();
using System;
using System.Collections.Generic;
using System.Text;
namespace ClassLibrary1
{
public class Class1
{
static Form1 dlg = new Form1();
public static void ShowForm()
{
dlg.ShowIcon = true;
dlg.Show();
}
public static void SetText(string MyText)
{
dlg.Text = "Form Text ";
dlg.SetText(MyText);
}
}
}
调用其方法时,通过将此dll引用到另一个C#应用程序成功加载此表单,即:
private void button1_Click(object sender, EventArgs e)
{
ClassLibrary1.Class1.ShowForm();
}
我能够完美地与形体互动
现在使用以下命令在Powershell中加载相同的命令:
[Reflection.Assembly]::LoadFile("D:\Playing\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll")
[ClassLibrary1.Class1]::ShowForm()
现在,它已成功加载到默认位置,但我无法与此表单交互,即我无法在其文本框中键入内容,也无法通过单击右角的关闭(x)按钮来移动甚至关闭此表单。每当我把鼠标放在它上面,它就会变成沙漏,也就是说,等待某个过程
为了验证表单是否未被挂起,我在Powershell提示符下调用了SetText:
[ClassLibrary1.Class1]::SetText("String from Powershell")
而且效果很好。TextBox正确地接收了此文本,但我仍然无法用鼠标与表单交互
我觉得,我必须手动设置它的窗口处理程序,即System.Windows.Forms.IWin32Window。
但我不知道是哪位处理者以及如何做到这一点
请引导。。。。非常感谢您提供任何其他技巧。您不能使用
form.show()
方法从PowerShell显示表单,因为它需要消息泵(而且PowerShell主机进程不提供)
以下是解决此问题的方法:
- 使用
或Form.ShowDialog()
,表单将有自己的消息泵Application.Run()
- 它将是模态的,然后您需要在另一个线程中运行它。我建议在
方法中使用后台线程和SetText()
BeginInvoke()
public static void ShowForm()
{
if (dlg != null)
dlg.BeginInvoke(new MethodInvoker(delegate { dlg.Dispose(); }));
ThreadPool.QueueUserWorkItem(delegate(object state)
{
Application.Run(_dlg = new Form1());
});
}
public static void SetText(string text)
{
_dlg.BeginInvoke(new MethodInvoker(delegate { dlg.SetText(text); }));
}
这样,Form1
将在另一个线程(具有自己的消息泵)中处于模态,并且您调用的PowerShell线程不会停止。它们之间的通信仍然可以通过消息分派(Invoke()
/BeginInvoke()
)实现
请注意,
SetText()
现在是异步的,要使其同步,只需将BeginInvoke()
替换为Invoke()
是否尝试使用Application.run()而不是Form.Show()运行它?我觉得它应该以正确的方式使用控制台应用程序中的表单。System.Windows.forms.application.Run(dlg)将表单显示为模式对话框,在关闭表单之前,我无法与Powershell交互。但您不能使用form.Show(),因为它没有可使用的消息泵。我会在单独的线程中使用ShowDialog()(或Application.Run())(在SetText()函数中使用BeginInvoke)。@Adriano:建议您重做您的注释作为答案,以便它可以被接受。@Adriano:此应用程序的目的是显示一个带有文本框等控件的对话框,然后传递文本消息以显示在该窗口中。如果我使用ShowDilog()或Application.Run(),这将阻止我在Powershell中发出命令。你能告诉我更多关于在SetText()中启动的信息吗?谢谢你有关于在C#中编写Ps cmdlet并使用winform交互的任何信息吗,因为应该已经有消息泵了?@FarrukhWaheed我刚才看到了你的消息…无论如何,消息泵是由两个东西提供的:Application.Run()或Form.ShowDialog()。即使您编写了C#cmdlet,它本身也不会有任何消息泵。是的,您是对的。一周前,我尝试了一个示例应用程序,得到了相同的结果。此外,还尝试了ShowUI()。它正在做我想做的,但没有提供足够的文档来采用它。@FarrukhWaheed我不知道那个项目。看起来还可以,但很遗憾,源代码不可用!啊。。我想,由于某些系统中断问题,源代码不可用。我只发现没有文件。