在 VB.NET 中连接到 OpenVPN

Connecting to OpenVPN in VB.NET

我想知道如何使用 VB.NET 连接到 OpenVPN,我曾尝试使用以下代码,但随后在命令行中出现错误消息“选项错误:在 [CMD-LINE] 中: 1:打开配置文件出错:C:\Users\Minetro300\Documents\connection.ovpn 使用 --help 获取更多信息。".

IO.File.WriteAllText((System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\vShield" & "\connection.ovpn"), My.Resources.OpenVPNCertificate)
IO.File.WriteAllText((System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\vShield" & "\connection.bat"), "openvpn " & System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\connection.ovpn")

Dim connect As System.Diagnostics.Process
connect = New System.Diagnostics.Process()
connect.StartInfo.FileName = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\vShield" & "\connection.bat"
connect.StartInfo.WindowStyle = ProcessWindowStyle.Normal

connect.Start()
connect.WaitForExit()

我本来想说我不知道​​您出错的原因,但这里有一些编写更好代码的建议,然后我意识到其中一个建议可以解决您的问题。查看您在这一行中指定的文件的路径:

IO.File.WriteAllText((System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\vShield" & "\connection.ovpn", My.Resources.OpenVPNCertificate)

现在查看您指定的路径,我认为应该是这一行中的同一文件:

IO.File.WriteAllText((System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\vShield" & "\connection.bat"), "openvpn " & System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\connection.ovpn")

你指定的读取文件的路径和你指定的写入文件的路径不一样,难怪不能读取文件?

我要给你的关于改进代码的建议是不要多次使用长表达式,而是使用它们一次并将结果分配给一个变量,然后重用该变量。如果你这样做了,那么你就不可能第二次搞砸了这条路。所以:

Dim ovpnFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "vShield\connection.ovpn"

您现在可以在需要该路径的任何地方使用该 ovpnFilePath 变量,这样您就不会尝试从与您写入的路径不同的路径读取。

建议的代码也包含其他几项改进。首先,导入您经常使用的名称空间,然后不在您的代码中使用它们。例如,System 已经导入,因此您不需要像现在这样在代码中使用 System.Environment。但是,更糟糕的是,您在某些地方使用 System.Environment 而在其他地方仅使用 Environment,有时甚至紧邻。那是糟糕的编码。如果我在您的代码中看到两个不同的东西,那么我应该能够假设它们是不同的,而不是无缘无故地以两种不同的方式编写的同一件事。您还应该导入 System.IO 命名空间,而不是重复使用 IO 限定 File

导入 System.IO 命名空间意味着您还可以使用不合格的 Path class 并且您应该使用 class 来组合部分路径而不是使用字符串级联。除此之外,永远不要将两个文字连接在一起。这很愚蠢,并且无缘无故地使您的代码复杂化。

仔细查看您的代码,我发现您多次使用两个文件路径,并且两个文件都在同一个文件夹中。我倾向于为这些路径执行此操作:

Dim folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "vShield")
Dim ovpnFilePath = Path.Combine(folderPath, "connection.ovpn")
Dim batFilePath = Path.Combine(folderPath, "connection.bat")

这将使您的代码不那么复杂,从而更易于阅读。它将消除您当前的问题并降低您赚取更多收入的可能性。

编辑:这是您编写的原始代码 "properly":

Dim folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "vShield")
Dim ovpnFilePath = Path.Combine(folderPath, "connection.ovpn")
Dim batFilePath = Path.Combine(folderPath, "connection.bat")

File.WriteAllText(ovpnFilePath, My.Resources.OpenVPNCertificate)
File.WriteAllText(batFilePath, String.Format("openvpn ""{0}""", ovpnFilePath))

Using connect As New Process(batFilePath)
    connect.StartInfo.WindowStyle = ProcessWindowStyle.Normal    
    connect.Start()
    connect.WaitForExit()
End Using

如您所见,一方面更容易阅读。它不会一遍又一遍地执行相同的操作,因此它消除了犯错误的机会,导致您首先 post 这个问题,即在写入和读取文件时使用不同的路径。

它也摆脱了不必要的限定命名空间。 SystemSystem.Diagnostics 已经默认导入,所以不需要对它们做任何事情。此代码假定您还导入了 System.IO,您可以在文件或项目级别执行此操作。

我还使用 String.Format 来创建命令行,因为它使用双引号引起来的文件路径更清晰。在这种情况下,这不是绝对必要的,但它确保如果文件路径中有空格,命令行仍然可以工作,这是完全可能的。

最后,它正确地处理了您通过使用 Using 块创建的 Process 对象,这导致在 Using 语句中创建的对象在End Using 语句。您应该始终处置您创建的任何支持它的对象。