2016-11-07 5 views
2

私が作っているアプリは、いくつかの基本的な追加ルール機能のためのデフォルトのWindowsファイアウォールのためのクイックインターフェイスです。アプリ。Process.Start()とBATファイルの使用(ファイルパス内のスペース)

私のアプリがどのように機能するようにするには、最終的に管理者権限が必要です。しかし、このようにして、.exeに許可したいファイルドラッグドロップを防止します。ですから、プロセスをエスカレートする必要があります。私はそれのためのコードを見つけました(.ver​​b = runas)

各ルール(したがって、各ルールの管理者プロンプト)を呼び出さないようにするために、より簡単な解決策は、ルールを.batファイル代わりに管理者権限で呼び出すことができます。

問題ビーイング:.BATは、アプリケーションディレクトリにあるVisual Basicの\プロジェクト\ \ドキュメント......などなど

: 私のアプリケーションディレクトリはDです。しかし、いつでも私は次のことを実行しよう:

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を使用する場合、私は同様の問題を取得します。

EDIT:

例私はこのコードを使用する.batファイルがある:私は私のプログラムの上昇cmd.exeとは独立に、それを呼び出したとき

netsh advfirewall firewall add rule name="testrule1" dir=IN remoteport=2083 desc="Testing firewall rule" action=block 
PAUSE 

.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 
+0

をあなたはx.FileName' 'に引用符を置く必要はありません。私がやったとき

これは私のために働きました。おそらく、エラーはあなたの.batファイルから来ています。 – Blorgbeard

+0

@Blorgbeardいや、.BATは以下の通りです: のnetshをadvfirewallは、私が直接それを実行した場合、それは完璧に動作 PAUSE を(ルールの定義を)ファイアウォール規則を追加します。私がプロセスを通して呼び出すのは、この問題のためにバットファイルを見つけることができないからです。 –

+0

'.filename =(" "+ my.application.info.directoryinfo + " \ exec.bat "" ")'してみましたか? – soja

答えて

0

3つのエスケープされた引用符を試してください。

.Filename = "cmd.exe" 
.Arguments = "/k " + """""" + My.Application.Info.DirectoryPath + "\exec.bat" + """""" 
.UseShellExecute = True 
.Verb = "runas" 
+0

それで、私はもっと近づいてきましたが、今では "フルパス"が実行可能な実行可能ファイルなどではないというエラーが表示されます。 引用符を減らすと元の問題に戻ります。 –

+0

.filenameをCMD.exeに、.argumentsを.batに設定した場合は、エラーが発生しますか? – lyst

+0

これは本当に愚かなバグです。私は多くのことを求めているわけではありません:\。今度は完全なパスを示しましたが、それでも実行可能ファイルではないとか、それ以外は使えると主張しています。 –

関連する問題