简体   繁体   English

采用组合框选择并将选择用作 SETX

[英]take combo box choice and use choice as SETX

I have the following code to create a combo box that shows a list of ports in use on the PC What I want to do is take the users choice of port and assign it to a system variable using the SETX command.我有以下代码来创建一个组合框,显示 PC 上正在使用的端口列表我想要做的是让用户选择端口并使用 SETX 命令将其分配给系统变量。 At the moment the user enters the port number manually in a batch file, the aim is to skip this step and replace it with the choice from the combo box目前用户在批处理文件中手动输入端口号,目的是跳过此步骤并用组合框中的选择替换它

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

    myPort = IO.Ports.SerialPort.GetPortNames()
    ComboBox1.Items.AddRange(myPort)

The batch file looks like this at present and works fine批处理文件目前看起来像这样并且工作正常

    set /p port= "What is your port number  "
    setx port "%port%"

So is there a way to remove the user having to enter the port number and have the batch file run its script using the choice from the combo box Thanks那么有没有一种方法可以删除必须输入端口号并使用组合框中的选项让批处理文件运行其脚本的用户谢谢

According to this post根据这篇文章

set modifies the current shell's (the window's) environment values, and the change is available immediately, but it is temporary. set修改当前 shell(窗口)的环境值,更改立即可用,但它是暂时的。 The change will not affect other shells that are running, and as soon as you close the shell, the new value is lost until such time as you run set again.更改不会影响正在运行的其他 shell,一旦您关闭 shell,新值就会丢失,直到您再次运行 set。

setx modifies the value permanently, which affects all future shells, but does not modify the environment of the shells already running. setx永久修改该值,这会影响所有未来的 shell,但不会修改已经运行的 shell 的环境。 You have to exit the shell and reopen it before the change will be available, but the value will remain modified until you change it again.您必须退出 shell 并重新打开它,才能更改可用,但该值将保持修改状态,直到您再次更改它。


For set /p port= "What is your port number: "对于set /p port= "What is your port number: "

one can use the following in VB.NET:可以在 VB.NET 中使用以下内容:

Environment.SetEnvironmentVariable("port", "COM5", EnvironmentVariableTarget.Process)

where "COM5" is your port number (replace this with the value from your ComboBox).其中“COM5”是您的端口号(将其替换为 ComboBox 中的值)。


For setx port "%port%" :对于setx port "%port%"

Permanent environment variables are stored in the registry: HKEY_CURRENT_USER\Environment .永久环境变量存储在注册表中: HKEY_CURRENT_USER\Environment

To set an environment variable in HKEY_CURRENT_USER\Environment , do one of the following.要在HKEY_CURRENT_USER\Environment中设置环境变量,请执行以下操作之一。

Option 1 :选项 1

'by specifying 'EnvironmentVariableTarget.User', the value will be updated in the registry (HKEY_CURRENT_USER\Environment)
Environment.SetEnvironmentVariable("port", "COM5", EnvironmentVariableTarget.User)

where "COM5" is your port number (replace this with the value from your ComboBox).其中“COM5”是您的端口号(将其替换为 ComboBox 中的值)。

Option 2 :选项 2

Add Imports添加导入

  • Imports Microsoft.Win32导入 Microsoft.Win32

SetUserEnvironmentVarReg :设置用户环境变量注册

Private Sub SetUserEnvironmentVarReg(name As String, val As String, Optional regView As RegistryView = RegistryView.Registry64)
    Using currentUserKey As RegistryKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, regView)
        Using envKey As RegistryKey = currentUserKey.OpenSubKey("Environment", True)
            If envKey IsNot Nothing Then
                'set value
                envKey.SetValue(name, val)
            End If
        End Using
    End Using
End Sub

Usage :用法

SetUserEnvironmentVarReg("port", "COM5")

where "COM5" is your port number (replace this with the value from your ComboBox).其中“COM5”是您的端口号(将其替换为 ComboBox 中的值)。


Let's create a test batch script.让我们创建一个测试批处理脚本。 The test batch script will allow one command-line argument which will allow it to be used with the different options shown below.测试批处理脚本将允许一个命令行参数,这将允许它与下面显示的不同选项一起使用。 If a command-line argument is supplied, the batch script will used the specified value, otherwise it will use the value inherited from the environment variable.如果提供命令行参数,批处理脚本将使用指定的值,否则它将使用从环境变量继承的值。

TestEnvVar.bat :测试环境变量.bat

@echo off

if not "%1" equ "" (
    set port=%1
)

echo port: %port%

One can use System.Diagnostics.Process to run the batch script.可以使用System.Diagnostics.Process来运行批处理脚本。

RunProcessInheritEnvironmentVar :运行过程继承环境变量

Private Sub RunProcessInheritEnvironmentVar(filename As String, portName As String)

    'set environment variable (process-level)
    Environment.SetEnvironmentVariable("port", portName, EnvironmentVariableTarget.Process)

    'set environment variable (user-level)
    'sets environment variable in HKEY_CURRENT_USER\Environment
    Environment.SetEnvironmentVariable("port", portName, EnvironmentVariableTarget.User)

    Dim startInfo As ProcessStartInfo = New ProcessStartInfo(filename) With {.CreateNoWindow = True, .RedirectStandardError = True, .RedirectStandardOutput = True, .UseShellExecute = False, .WindowStyle = ProcessWindowStyle.Hidden}

    Using p As Process = New Process() With {.EnableRaisingEvents = True, .StartInfo = startInfo}

        AddHandler p.ErrorDataReceived, Sub(sender As Object, e As DataReceivedEventArgs)
                                            If Not String.IsNullOrEmpty(e.Data) Then
                                                'ToDo: add desired code
                                                Debug.WriteLine("error: " & e.Data)
                                            End If
                                        End Sub

        AddHandler p.OutputDataReceived, Sub(sender As Object, e As DataReceivedEventArgs)
                                             If Not String.IsNullOrEmpty(e.Data) Then
                                                 'ToDo: add desired code
                                                 Debug.WriteLine("output: " & e.Data)
                                             End If
                                         End Sub

        p.Start()

        p.BeginErrorReadLine()
        p.BeginOutputReadLine()

        'wait for exit
        p.WaitForExit()

    End Using
End Sub

Usage :用法

RunProcessInheritEnvironmentVar("C:\Temp\TestEnvVar.bat", "COM5")

where "COM5" is your port number (replace this with the value from your ComboBox).其中“COM5”是您的端口号(将其替换为 ComboBox 中的值)。


It's not clear whether or not you actually need to set the environment variable permanently (ie: in HKEY_CURRENT_USER\Environment).不清楚您是否真的需要永久设置环境变量(即:在 HKEY_CURRENT_USER\Environment 中)。 If the environment variable is only being used for the batch script being executed, one may consider one of the alternate methods shown below.如果环境变量仅用于正在执行的批处理脚本,则可以考虑下面显示的替代方法之一。

When using System.Diagnostics.Process an environment variable can be set using ProcessStartInfo.EnvironmentVariables which sets the environment variable within the scope of the System.Diagnostics.Process process.使用System.Diagnostics.Process时,可以使用ProcessStartInfo.EnvironmentVariables设置环境变量,它在System.Diagnostics.Process进程的 scope 内设置环境变量。 The code below doesn't change the value in the registry.下面的代码不会更改注册表中的值。

RunProcessSetEnvironmentVar :运行过程设置环境变量

Private Sub RunProcessSetEnvironmentVar(filename As String, portName As String)
    Dim startInfo As ProcessStartInfo = New ProcessStartInfo(filename) With {.CreateNoWindow = True, .RedirectStandardError = True, .RedirectStandardOutput = True, .UseShellExecute = False, .WindowStyle = ProcessWindowStyle.Hidden}

    'add environment variable
    startInfo.Environment.Add("port", portName)

    Using p As Process = New Process() With {.EnableRaisingEvents = True, .StartInfo = startInfo}

        AddHandler p.ErrorDataReceived, Sub(sender As Object, e As DataReceivedEventArgs)
                                            If Not String.IsNullOrEmpty(e.Data) Then
                                                'ToDo: add desired code
                                                Debug.WriteLine("error: " & e.Data)
                                            End If
                                        End Sub

        AddHandler p.OutputDataReceived, Sub(sender As Object, e As DataReceivedEventArgs)
                                             If Not String.IsNullOrEmpty(e.Data) Then
                                                 'ToDo: add desired code
                                                 Debug.WriteLine("output: " & e.Data)
                                             End If
                                         End Sub


        p.Start()

        p.BeginErrorReadLine()
        p.BeginOutputReadLine()

        'wait for exit
        p.WaitForExit()

    End Using
End Sub

Usage :用法

RunProcessSetEnvironmentVar("C:\Temp\TestEnvVar.bat", "COM5")

where "COM5" is your port number (replace this with the value from your ComboBox).其中“COM5”是您的端口号(将其替换为 ComboBox 中的值)。


Lastly, let's look at how one could specify the port name as an argument because the test batch script allows command-line arguments. The code below doesn't change the value in the registry.最后,让我们看看如何将端口名称指定为参数,因为测试批处理脚本允许命令行 arguments。下面的代码不会更改注册表中的值。

RunProcessWithArgument : RunProcessWithArgument

Private Sub RunProcessWithArgument(filename As String, Optional arguments As String = Nothing)
    Dim startInfo As ProcessStartInfo = New ProcessStartInfo(filename) With {.CreateNoWindow = True, .RedirectStandardError = True, .RedirectStandardOutput = True, .UseShellExecute = False, .WindowStyle = ProcessWindowStyle.Hidden}

    If Not String.IsNullOrEmpty(arguments) Then
        startInfo.Arguments = arguments
    End If

    Using p As Process = New Process() With {.EnableRaisingEvents = True, .StartInfo = startInfo}

        AddHandler p.ErrorDataReceived, Sub(sender As Object, e As DataReceivedEventArgs)
                                            If Not String.IsNullOrEmpty(e.Data) Then
                                                'ToDo: add desired code
                                                Debug.WriteLine("error: " & e.Data)
                                            End If
                                        End Sub

        AddHandler p.OutputDataReceived, Sub(sender As Object, e As DataReceivedEventArgs)
                                             If Not String.IsNullOrEmpty(e.Data) Then
                                                 'ToDo: add desired code
                                                 Debug.WriteLine("output: " & e.Data)
                                             End If
                                         End Sub


        p.Start()

        p.BeginErrorReadLine()
        p.BeginOutputReadLine()

        'wait for exit
        p.WaitForExit()

    End Using
End Sub

Usage用法

RunProcessWithArgument("C:\Temp\TestEnvVar.bat", "COM5")

where "COM5" is your port number (replace this with the value from your ComboBox).其中“COM5”是您的端口号(将其替换为 ComboBox 中的值)。


I've shown a variety of methods that can be used to specify an environment variable that can be used for a batch script depending upon your needs.我已经展示了多种方法,可用于指定可根据您的需要用于批处理脚本的环境变量。 For a slight variation of System.Diagnostics.Process usage see here .有关System.Diagnostics.Process用法的细微变化,请参见此处


Update :更新

When using System.Diagnostics.Process , one can also use StandardInput to provide value(s) for prompt(s).使用System.Diagnostics.Process时,还可以使用StandardInput为提示提供值。

TestEnvVar.bat :测试环境变量.bat

@echo off

set /p port= "What is your port number:  "
setx port "%port%"

echo port: %port%

for /f "delims=" %%a in ('^(reg query "HKCU\Environment" /v "port" ^|find /i "port"^)') do (
  echo %%a
)

RunProcessWithStandardInput : RunProcessWithStandardInput

Private Sub RunProcessWithStandardInput(filename As String, portName As String)
    If String.IsNullOrEmpty(filename) Then
        Throw New Exception("Error: 'filename' is null or empty.")
    ElseIf Not System.IO.File.Exists(filename) Then
        Throw New Exception($"Error: '{filename}' could not be found.")
    End If

    If String.IsNullOrEmpty(portName) Then
        Throw New Exception("Error: 'portName' is null or empty.")
    End If

    Dim startInfo As ProcessStartInfo = New ProcessStartInfo(filename) With {.CreateNoWindow = True, .RedirectStandardError = True, .RedirectStandardInput = True, .RedirectStandardOutput = True, .UseShellExecute = False, .WindowStyle = ProcessWindowStyle.Hidden}

    Using p As Process = New Process() With {.EnableRaisingEvents = True, .StartInfo = startInfo}

        AddHandler p.ErrorDataReceived, Sub(sender As Object, e As DataReceivedEventArgs)
                                            If Not String.IsNullOrEmpty(e.Data) Then
                                                'ToDo: add desired code
                                                Debug.WriteLine("error: " & e.Data)
                                            End If
                                        End Sub

        AddHandler p.OutputDataReceived, Sub(sender As Object, e As DataReceivedEventArgs)
                                             If Not String.IsNullOrEmpty(e.Data) Then
                                                 'ToDo: add desired code
                                                 Debug.WriteLine("output: " & e.Data)
                                             End If
                                         End Sub


        p.Start()

        p.BeginErrorReadLine()
        p.BeginOutputReadLine()

        Using sw As System.IO.StreamWriter = p.StandardInput
            'provide values for each input prompt
            'ToDo: add values for each input prompt - changing the for loop as necessary
            'Note: Since we only have 1 prompt, using a loop Is unnecessary - a single 'WriteLine' statement would suffice

            'if there are additional prompts add them below; else if (i = 1)...
            For i As Integer = 0 To 1
                If i = 0 Then
                    'write port name to StandardInput
                    sw.WriteLine(portName)
                End If
            Next
        End Using

        'wait for exit
        p.WaitForExit()
    End Using
End Sub

Usage :用法

RunProcessWithStandardInput("C:\Temp\TestEnvVar.bat", "COM5")

where "COM5" is your port number (replace this with the value from your ComboBox).其中“COM5”是您的端口号(将其替换为 ComboBox 中的值)。

Additional Resources :其他资源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM