从.bat文件中运行带有Winforms的PowerShell脚本

发布于 2025-01-21 23:40:05 字数 8 浏览 0 评论 0原文

continue

I have made a Powershell script that creates a simple Windows Forms UI. I would like to call it from a .bat file. I tried the simple way, but it doesn't find the classes that I use.
Then I tried running the script as admin using this command:

    @echo off
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""G:\file.ps1""' -Verb RunAs}"

pause

But it says that all the types used couldn't be found, like System.Windows.Forms.Label

Here are a few lines from the .ps1 script:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Text.RegularExpressions
...

$window = New-Object System.Windows.Forms.Form
$window.Width = 400
$window.Height = 600
....
[void]$window.ShowDialog()

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陌路黄昏 2025-01-28 23:40:05

这并不是严格的答案,但是我按原样测试了您的代码,即使没有作为管理员运行它,它也对我有用。

也就是说,我的第一个批处理文件具有以下内容:

PowerShell -NoProfile -ExecutionPolicy Bypass -File C:\file.ps1

它运行良好。它显示了我能够关闭的空白形式。然后,我测试了您的批处理文件,也可以正常工作。当作为管理员运行时,它在打开表单之前打开了二级PowerShell控制台。

您提到它找不到您使用的类。您确定这些类未在您的PowerShell配置文件脚本($ profile)中创建或导入吗?

如果是这样,请注意批处理文件中的命令行包括“ -noprofile”,它将跳过加载任何配置文件脚本。


编辑:我还没有足够的声誉发布评论,因此我将在这里跟进

以下内容:

确定,然后我会发现每个类型找不到的错误,例如
system.windows.forms.label

确切的错误消息是什么?该行看起来像该引用System.windows.forms.label?

我修改了自己的测试脚本,如下所示:

Add-Type -AssemblyName System.Windows.Forms
$window = New-Object System.Windows.Forms.Form
$window.Width = 400
$window.Height = 600
$label = New-Object System.Windows.Forms.Label
$label.Text = 'This is a test'
$window.Controls.Add($label)
[void]$window.ShowDialog()

我使用提供的相同批处理文件运行了该片段,并且没有错误就可以了。

我们还没有发现一些事情。


更新2:

好的,我现在看到问题了。您正在尝试根据通过附加类型导入的.NET类型定义PowerShell类。问题在于,类定义在解析过程中解决了,而不是在运行时解决,这意味着尚未执行添加类型命令。

此问题在以下答案中解决: https://stackoverflow.com/a/34637458/188815893
作为对使用PowerShell(v5)类中的.NET对象的答案

简而言之,有两种解决方案,有两种解决方案:

  1. 将类定义放在单独的脚本中,该脚本被调用后,该脚本从父脚本调用,或者称为

  2. 将类定义包装在此处串联并使用Invoke-expextression。

This isn't strictly an answer, but I tested your code as is and it worked for me, even without running it as an admin.

That is, my first batch file had the following:

PowerShell -NoProfile -ExecutionPolicy Bypass -File C:\file.ps1

and it worked fine. It showed a blank form which I was able to close. Then, I tested your batch file and it worked fine too. When running as an admin, it opened a secondary PowerShell console before opening the form.

You mentioned that it doesn't find the classes that you use. Are you sure those classes aren't being created or imported in your PowerShell profile script ($PROFILE)?

If so, note that the command line in your batch file includes "-NoProfile", which will skip loading any profile scripts.


Edit: I don't have enough reputation yet to post comments, so I will follow up here

In response to:

Ok then I get an error for each type that it's not found, like
System.Windows.Forms.Label

What is the exact error message? What does the line look like that references System.Windows.Forms.Label?

I modified my own test script as follows:

Add-Type -AssemblyName System.Windows.Forms
$window = New-Object System.Windows.Forms.Form
$window.Width = 400
$window.Height = 600
$label = New-Object System.Windows.Forms.Label
$label.Text = 'This is a test'
$window.Controls.Add($label)
[void]$window.ShowDialog()

I ran this snippet using the same batch file you provided, and it started fine with no errors.

There's something going on that we haven't discovered yet.


Update 2:

Okay I see the problem now. You're attempting to define PowerShell classes based on .NET types imported via Add-Type. The problem is that class definitions are resolved during parsing, and not at runtime, meaning the Add-Type commands haven't been executed yet.

This issue is addressed in the following answer: https://stackoverflow.com/a/34637458/18815893
as an answer to Using .NET objects within a Powershell (V5) class

In short, there are two solutions offered:

  1. Put the class definitions in a separate script that is dot-sourced from the parent script after the Add-Type definitions are called, or

  2. Wrap the class definitions in a here-string and use Invoke-Expression.

星星的軌跡 2025-01-28 23:40:05

我遇到了同样的问题,每当我尝试从.bat中运行GUI PowerShell脚本时,就找不到[System.Windows.FormS.Type]的类型,但是它可以使用完全相同的ISE PowerShell使用。

我提出了解决方案:

创建一个新脚本,然后首先添加声明(main.ps1):

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

在另一个脚本中,将GUI脚本(GUI.PS1)放置:

<# Insert your GUI script #>
$Form = New-Object System.Windows.Forms.Form
$Form.ShowDialog()

然后添加第一个脚本(main.ps1) GUI脚本的采购

就像这样:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

. "C:\Admin\PathToYourScript\GUI.ps1"

最后,创建.bat(runscript.bat):

PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Admin\PathToYourScript\Main.ps1"

现在您可以运行Runscript.bat,现在应该显示GUI。

I had the same problem, whenever I tried to run a GUI powershell script from .bat, the type [System.Windows.Forms.Type] were not find, however it worked on ISE powershell with the exact same script.

I came up with the solution :

Create a new script and first add the declaration (Main.ps1) :

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

And in another script, put your GUI script (GUI.ps1) :

<# Insert your GUI script #>
$Form = New-Object System.Windows.Forms.Form
$Form.ShowDialog()

Then add in the first script (Main.ps1) the dot sourcing of the GUI script

Just like this :

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

. "C:\Admin\PathToYourScript\GUI.ps1"

Finally, create .bat (RunScript.bat) :

PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Admin\PathToYourScript\Main.ps1"

And now you can run RunScript.bat, it should now show the GUI.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文