大家早上好,
我在使用 powershell 脚本时遇到了问题。
语境
我正在尝试创建一个程序来在 powershell 中编辑 tf2 pop 文件,现在我正在尝试创建一个程序来打开一个 txt 文件,显示每个 wavespawn 的内容以及一个用于复制 wavespawn 的按钮。
这是我目前在获得一些帮助后编写的 powershell 脚本。
# Import necessary assemblies for Windows Forms
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Function to create OpenFileDialog
function Show-OpenFileDialog {
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.InitialDirectory = [System.Environment]::GetFolderPath('MyDocuments')
$openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"
$openFileDialog.Title = "Select a Text File"
$result = $openFileDialog.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
return $openFileDialog.FileName
} else {
return $null
}
}
# Function to load file content and extract WaveSpawn sections
function Load-FileContent {
param (
[string]$filePath,
[System.Windows.Forms.ListBox]$listBox,
[ref]$waveSpawnDetails
)
$listBox.Items.Clear()
$waveSpawnDetails.Value.Clear()
if (Test-Path $filePath) {
$content = Get-Content -Path $filePath -Raw
# Extract all WaveSpawn sections with a more robust regex pattern
$waveSpawns = [regex]::Matches($content, 'WaveSpawn\s*\{(?:[^\{\}]*|(?<Open>\{)|(?<-Open>\}))*\}(?(Open)(?!))')
$waveSpawns | ForEach-Object {
$waveSpawn = $_.Value
if ($waveSpawn -match 'Name\s+(\w+)') {
$name = $matches[1]
$listBox.Items.Add($name)
$waveSpawnDetails.Value[$name] = $waveSpawn
}
}
} else {
[System.Windows.Forms.MessageBox]::Show("File not found: $filePath", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
}
}
# Function to display details of the selected WaveSpawn
function Show-WaveSpawnDetails {
param (
[string]$waveSpawnName,
[System.Windows.Forms.TextBox]$textBox,
[hashtable]$waveSpawnDetails
)
if ($waveSpawnDetails.ContainsKey($waveSpawnName)) {
$textBox.Text = $waveSpawnDetails[$waveSpawnName]
} else {
$textBox.Text = "WaveSpawn details not found."
}
}
# Main form
$form = New-Object Windows.Forms.Form
$form.Text = "WaveSpawns"
$form.Size = New-Object Drawing.Size(800, 600)
# ListBox to display WaveSpawns
$listBox = New-Object Windows.Forms.ListBox
$listBox.Size = New-Object Drawing.Size(300, 500)
$listBox.Location = New-Object Drawing.Point(10, 10)
# TextBox to display selected WaveSpawn details
$textBox = New-Object Windows.Forms.TextBox
$textBox.Size = New-Object Drawing.Size(450, 500)
$textBox.Location = New-Object Drawing.Point(320, 10)
$textBox.Multiline = $true
$textBox.ScrollBars = [System.Windows.Forms.ScrollBars]::Vertical
# Button to copy WaveSpawn details to clipboard
$copyButton = New-Object Windows.Forms.Button
$copyButton.Text = "Copy"
$copyButton.Size = New-Object Drawing.Size(75, 23)
$copyButton.Location = New-Object Drawing.Point(320, 520)
$copyButton.Add_Click({
Set-Clipboard -Value $textBox.Text
[System.Windows.Forms.MessageBox]::Show("WaveSpawn copied to clipboard!")
})
# Button to open file
$openButton = New-Object Windows.Forms.Button
$openButton.Text = "Open File"
$openButton.Size = New-Object Drawing.Size(75, 23)
$openButton.Location = New-Object Drawing.Point(10, 520)
$openButton.Add_Click({
$filePath = Show-OpenFileDialog
if ($filePath) {
Load-FileContent -filePath $filePath -listBox $listBox -waveSpawnDetails ([ref]$waveSpawnDetails)
}
})
# Add event handler for ListBox selection
$listBox.SelectedIndexChanged.Add({
$selectedWaveSpawnName = $listBox.SelectedItem.ToString()
Show-WaveSpawnDetails -waveSpawnName $selectedWaveSpawnName -textBox $textBox -waveSpawnDetails $waveSpawnDetails
})
# Add controls to form
$form.Controls.Add($listBox)
$form.Controls.Add($textBox)
$form.Controls.Add($copyButton)
$form.Controls.Add($openButton)
# Initialize hashtable to store WaveSpawn details
$global:waveSpawnDetails = @{}
# Show the form
$form.ShowDialog()
测试“pop”文件
//This mission is a dummy mission and is probably not working, it just here to test the powershell script in "real condition"
#base robot_standard.pop
#base robot_giant.pop
WaveSchedule
{
StartingCurrency 900
RespawnWaveTime 4
CanBotsAttackWhileInSpawnRoom no
Mission
{
Objective DestroySentries
BeginAtWave 1
RunForThisManyWaves 3
InitialCooldown 30
CooldownTime 30
DesiredCount 1
Where spawnbot_mission_sentrybuster
TFBot
{
Template T_TFBot_SentryBuster
}
}
Wave //wave 1
{
StartWaveOutput
{
Target wave_start_relay
Action Trigger
}
DoneOutput
{
Target wave_finished_relay
Action Trigger
}
WaveSpawn
{
Name wave1
TotalCurrency 300
TotalCount 4
MaxActive 6
SpawnCount 1
WaitBeforeStarting 0
WaitBetweenSpawns 12
Where spawnbot
TFBot
{
Template T_TFBot_Giant_Pyro
Tag bot_giant
Attributes AlwaysFireWeapon
}
}
WaveSpawn
{
Name wave1
TotalCurrency 100
TotalCount 24
MaxActive 12
SpawnCount 2
WaitBeforeStarting 2
WaitBetweenSpawns 2.5
Where spawnbot_side
Squad
{
TFBot
{
Class Soldier
Skill normal
}
TFBot
{
Template T_TFBot_Medic_QuickFix
Tag bot_squad_member
ItemAttributes
{
ItemName "The Quick-Fix"
"ubercharge rate bonus" 0.1
}
}
}
}
WaveSpawn
{
Name wave2
WaitForAllSpawned w1a
TotalCurrency 100
TotalCount 3
MaxActive 3
SpawnCount 1
WaitBeforeStarting 7
WaitBetweenSpawns 7
Where spawnbot
TFBot
{
Template T_TFBot_Giant_Demoman
Tag bot_giant
}
}
WaveSpawn
{
Name wave2
WaitForAllSpawned w1a
TotalCurrency 300
TotalCount 1
MaxActive 1
SpawnCount 1
WaitBeforeStarting 2
WaitBetweenSpawns 1
FirstSpawnOutput
{
Target boss_spawn_relay
Action Trigger
}
Tank
{
Name "Tank"
Health 15000
Speed 70
StartingPathTrackNode tank_path_1
OnKilledOutput
{
Target boss_dead_relay
Action Trigger
}
OnBombDroppedOutput
{
Target boss_deploy_relay
Action Trigger
}
}
}
WaveSpawn
{
Name wave3
WaitForAllSpawned w1b
TotalCurrency 50
TotalCount 2
MaxActive 2
SpawnCount 1
WaitBeforeStarting 4
WaitBetweenSpawns 7
Where spawnbot_side
TFBot
{
Template T_TFBot_Giant_Scout_FAN
Tag bot_giant
}
}
WaveSpawn
{
Name wave3
WaitForAllSpawned w1b
Support 1
TotalCurrency 50
TotalCount 50
MaxActive 10
Support Limited
SpawnCount 5
WaitBeforeStarting 7
WaitBetweenSpawns 1
Where spawnbot_invasion
TFBot
{
Class Demoman
}
}
}
}
此外,当我尝试复制 wavespawn 时,这里还出现了错误消息,这是我收到的唯一错误。
mpossible d’appeler une méthode dans une expression Null.
Au caractère P:\Document\Fichier texte\Switch_supervision - Copie.ps1:99 : 1
+ $listBox.SelectedIndexChanged.Add({
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation : (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
有人能帮我弄清楚脚本发生了什么以及为什么两个主要功能不起作用吗?
更新:如果有人感兴趣的话@Someone 已经找到了解决方案,这里有有效的代码:
# Import necessary assemblies for Windows Forms
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Function to create OpenFileDialog
function Show-OpenFileDialog {
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.InitialDirectory = [System.Environment]::GetFolderPath('MyDocuments')
$openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"
$openFileDialog.Title = "Select a Text File"
$result = $openFileDialog.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
return $openFileDialog.FileName
} else {
return $null
}
}
# Function to load file content and extract WaveSpawn sections
function Load-FileContent {
param (
[string]$filePath,
[System.Windows.Forms.ListBox]$listBox,
[ref]$waveSpawnDetails
)
$listBox.Items.Clear()
$waveSpawnDetails.Value.Clear()
if (Test-Path $filePath) {
$content = Get-Content -Path $filePath -Raw
# Extract all WaveSpawn sections with a more robust regex pattern
$waveSpawns = [regex]::Matches($content, 'WaveSpawn\s*\{(?:[^\{\}]*|(?<Open>\{)|(?<-Open>\}))*\}(?(Open)(?!))')
$waveSpawns | ForEach-Object {
$waveSpawn = $_.Value
if ($waveSpawn -match 'Name\s+(\w+)') {
$name = $matches[1]
$listBox.Items.Add($name)
$waveSpawnDetails.Value[$name] = $waveSpawn
}
}
} else {
[System.Windows.Forms.MessageBox]::Show("File not found: $filePath", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
}
}
# Function to display details of the selected WaveSpawn
function Show-WaveSpawnDetails {
param (
[string]$waveSpawnName,
[System.Windows.Forms.TextBox]$textBox,
[hashtable]$waveSpawnDetails
)
if ($waveSpawnDetails.ContainsKey($waveSpawnName)) {
$textBox.Text = $waveSpawnDetails[$waveSpawnName]
} else {
$textBox.Text = "WaveSpawn details not found."
}
}
# Main form
$form = New-Object Windows.Forms.Form
$form.Text = "WaveSpawns"
$form.Size = New-Object Drawing.Size(800, 600)
# ListBox to display WaveSpawns
$listBox = New-Object Windows.Forms.ListBox
$listBox.Size = New-Object Drawing.Size(300, 500)
$listBox.Location = New-Object Drawing.Point(10, 10)
# TextBox to display selected WaveSpawn details
$textBox = New-Object Windows.Forms.TextBox
$textBox.Size = New-Object Drawing.Size(450, 500)
$textBox.Location = New-Object Drawing.Point(320, 10)
$textBox.Multiline = $true
$textBox.ScrollBars = [System.Windows.Forms.ScrollBars]::Vertical
# Button to copy WaveSpawn details to clipboard
$copyButton = New-Object Windows.Forms.Button
$copyButton.Text = "Copy"
$copyButton.Size = New-Object Drawing.Size(75, 23)
$copyButton.Location = New-Object Drawing.Point(320, 520)
$copyButton.Add_Click({
Set-Clipboard -Value $textBox.Text
[System.Windows.Forms.MessageBox]::Show("WaveSpawn copied to clipboard!")
})
# Button to open file
$openButton = New-Object Windows.Forms.Button
$openButton.Text = "Open File"
$openButton.Size = New-Object Drawing.Size(75, 23)
$openButton.Location = New-Object Drawing.Point(10, 520)
$openButton.Add_Click({
$filePath = Show-OpenFileDialog
if ($filePath) {
Load-FileContent -filePath $filePath -listBox $listBox -waveSpawnDetails ([ref]$waveSpawnDetails)
}
})
# Add event handler for ListBox selection
$listBox.Add_SelectedIndexChanged({
$selectedWaveSpawnName = $listBox.SelectedItem.ToString()
Show-WaveSpawnDetails -waveSpawnName $selectedWaveSpawnName -textBox $textBox -waveSpawnDetails $waveSpawnDetails
})
# Add controls to form
$form.Controls.Add($listBox)
$form.Controls.Add($textBox)
$form.Controls.Add($copyButton)
$form.Controls.Add($openButton)
# Initialize hashtable to store WaveSpawn details
$global:waveSpawnDetails = @{}
# Show the form
$form.ShowDialog()