【发布时间】:2017-03-20 07:37:45
【问题描述】:
我正在制作的应用程序只是默认 Windows 防火墙的一个快速界面,用于一些基本的添加规则功能,因为我打开了很多端口和应用程序。
为了让我的应用程序按我想要的方式运行,我需要它最终拥有管理员权限。但是,这样开始会阻止我想要允许 .exe 的文件拖放。所以我需要升级一个流程——很简单。我找到了它的代码(.verb = runas)
为了避免为每个规则调用它(以及因此每个规则的管理员提示),我决定更简单的解决方案是将规则写入一个 .bat 文件并使用 admin privs 调用它。
问题是: 我的应用程序目录是D:\Documents\Visual Basic\Projects......等等等等
.bat 位于应用程序目录中。但是,每当我尝试运行以下命令时:
dim x as new processstartinfo()
with x
.filename = (controlchars.quote + my.application.info.directoryinfo +
"\exec.bat" + controlchars.quote)
other settings....
process.start(x)
我在控制台上得到的(因为我可以使用 cmd /k 让它保持不变)是这个错误:
D:\Documents\Visual is not a valid command or couldn't be found.
回忆路径是:D:\Documents\Visual Basic\Projects
很明显,问题与那个空白有关。但是,我终生无法在网上找到可行的解决方案。我使用了转义引号、单独的变量、controlchars.quote.... 似乎没有任何效果。
我必须使用 process.start 来进行升级,所以我无法解决该部分......
如果我使用 .workingdirectory,我会遇到类似的问题。
编辑:
我在这段代码中使用的 .bat 示例是:
netsh advfirewall firewall add rule name="testrule1" dir=IN remoteport=2083 desc="Testing firewall rule" action=block
PAUSE
当我在程序的提升的 cmd.exe INDEPENDENT 中调用 .bat 时,它可以完美运行。程序本身似乎找不到 .bat 文件,这没有任何意义,因为我从编写 .bat 的位置复制/粘贴了它的路径。
Private Sub btn_commit_Click(sender As Object, e As EventArgs) Handles btn_commit.Click
Dim cmd_list As New List(Of String)
If lb_rules_list.Items.Count = 0 Then
MsgBox("There are no rules to add. Create one first.", MsgBoxStyle.Exclamation, "Error: No rules!")
Else
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter(My.Application.Info.DirectoryPath + "\log.txt", True)
For Each i As firewall_rule In lb_rules_list.Items
Dim cmd As String = ""
If i.path <> "" Then
cmd = "netsh advfirewall firewall add rule name=" + Chr(34) + i.name + Chr(34) + " dir=" + i.direction + " program=" + Chr(34) + i.path + Chr(34) + " action=" + i.action.ToLower
If i.desc <> "" Then
cmd = cmd + " desc=" + ControlChars.Quote + i.desc.ToString + ControlChars.Quote
End If
Else
If i.port_type <> "" Then
cmd = "netsh advfirewall firewall add rule name=" + Chr(34) + i.name + Chr(34) + " dir=" + i.direction + " remoteport=" + Chr(34) + i.ports + Chr(34) + " action=" + i.action.ToLower +
" protocol=" + i.port_type
If i.desc <> "" Then
cmd = cmd + " desc=" + ControlChars.Quote + i.desc.ToString + ControlChars.Quote
End If
End If
End If
Dim wrstr As String = ""
wrstr = "NAME: " + i.name + ControlChars.NewLine
If i.desc <> "" Then
wrstr = wrstr + " DESCRIPTION" + ControlChars.NewLine + " " + i.desc + ControlChars.NewLine
End If
wrstr = wrstr + " TYPE: " + If(i.path <> "", "Application", "Port(s)") + ControlChars.NewLine
wrstr = wrstr + " Direction: " + i.direction + ControlChars.NewLine
If i.path <> "" Then
wrstr = wrstr + " Path: " + i.path + ControlChars.NewLine
Else
wrstr = wrstr + " Port(s): " + i.ports + ControlChars.NewLine + " Protocol: " + i.port_type + ControlChars.NewLine
End If
wrstr = wrstr + ControlChars.NewLine
file.Write(wrstr)
cmd_list.Add(cmd)
Next
file.Close()
Using batwriter As New IO.StreamWriter(My.Application.Info.DirectoryPath + "\exec.bat")
For Each c As String In cmd_list
batwriter.WriteLine(c)
Next
batwriter.WriteLine("PAUSE")
batwriter.Flush()
batwriter.Close()
End Using
Try
Dim proc As New ProcessStartInfo()
With proc
'.WindowStyle = ProcessWindowStyle.Hidden
.UseShellExecute = True
.FileName = ("""" + My.Application.Info.DirectoryPath + "\exec.bat""")
.Verb = "runas"
End With
Process.Start(proc)
Catch ex As Exception
MsgBox("Process failed: " + ex.Message)
End Try
My.Computer.FileSystem.DeleteFile(My.Application.Info.DirectoryPath + "\exec.bat")
lb_rules_list.Items.Clear()
rb_prt_tcp.Checked = False
rb_prt_udp.Checked = False
For Each i As TextBox In Me.Controls.OfType(Of TextBox)
i.Text = ""
Next
End If
End Sub
【问题讨论】:
-
您不需要在
x.FileName中加上引号。也许错误来自您的 .bat 文件。 -
@Blorgbeard 是的,.bat 如下: netsh advfirewall firewall add rule (rule definitions) PAUSE 如果我直接运行它,它可以完美运行。只有当我通过进程调用它时 - 这是因为由于这个问题它找不到 bat 文件。
-
你试过
.filename = ("" + my.application.info.directoryinfo + "\exec.bat""")吗? -
@soja 是的,我现在才这样做。不幸的是,没有骰子。也许很明显我缺少什么,所以我上传了发生这种情况的 button.click() 处理程序并更新了我的帖子。
-
为什么你是一个.bat。您知道有 API 可以让这一切变得简单吗?
标签: vb.net batch-file process.start