使用批处理文件向系统变量路径中添加一行

6

我一直在寻找一个脚本,可以让我向当前系统变量路径的末尾添加文本。是否有建议我如何做到这一点?(具体来说,是将";C:\Program Files (x86)\Java\jre7\bin\java.exe"添加到现有文本中)


1
你可以这样做,但是它只能持续到批处理文件完成。如果你想要使其成为永久更改,这种方法行不通。 - Ken White
2个回答

4
echo Set objShell = CreateObject( "WScript.Shell" ) > %TEMP%\sp.vbs
echo Set objSystemEnv = objShell.Environment( "SYSTEM" ) >> %TEMP%\sp.vbs
echo objSystemEnv("Path") = objSystemEnv("Path") ^& ";C:\Program Files (x86)\Java\jre7\bin" >> %TEMP%\sp.vbs
cscript.exe /nologo %TEMP%\sp.vbs
del %TEMP%\sp.vbs

这个CMD必须以管理员身份运行,否则cscript.exe只会写入“权限被拒绝”并且什么也不会发生。


1
@KenWhite,这是一个批处理文件,它可以完成任务。C#源代码无法做到以下两点:1. 从批处理文件中实现更加困难;2. 在Vista之前的系统中,通常没有csc.exe可用。 - Soonts
你没有理解我的观点。问题特别标记为“windows batch”,而你的答案并没有使用Windows批处理文件来修改“PATH”。它使用批处理文件编写和执行不同类型的脚本,就像我上面说的那样。这不是问题的答案。你说:“使用VBScript,但增加从批处理文件中编写脚本文件的开销,而不是在NotePad中编写。”(顺便说一句,我没有对你的回答进行投票。只是指出它没有回答问题。) - Ken White
1
@KenWhite,我认为当人们问类似“我需要一个脚本来…”的问题时,他们很少会对各种脚本环境的能力进行学术研究。相反,他们通常需要脚本来完成某些任务。 - Soonts
1
@KenWhite,为什么你一直说在纯CMD中这是不可能的呢?你可以使用“reg query”命令读取“HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment”键中的“Path”值,然后使用“for /F”提取所需数据,最后使用“setx /M”更新变量。但这种方法比我提出的解决方案更加复杂和容易出错。 - Soonts
@KenWhite,现在谈谈你对C# / Java类比的看法。这里的主要区别在于,通常由于性能和部署问题,从C#调用Java是行不通的。另一方面,从CMD创建和运行VBScript可以在全世界的Windows PC上工作。 - Soonts
显示剩余2条评论

1

如果您想要最简单的解决方案,可以在Windows 7中使用SETX命令:

SETX PATH "%PATH%;C:\New Added Folder"

PS1:如果您希望SETX命令对HKLM键执行更改,请使用-M参数。

PS2:更改是永久性的,但您需要重新启动用户会话或控制台。

如果您想要更专业一点的东西,那么您可以使用我用Ruby编写的实用程序PATHS,并为Windows制作了一个可执行文件。

PATHS.EXE

http://exoshare.com/download.php?uid=1TKIOMR6

enter image description here

enter image description here

enter image description here

选项:

/? (或) -help | 显示此信息。

-l (或) -list | 列出条目。

-c (或) -clean | 清除路径中的重复和无效目录。

-r (或) -reset | 将路径重置为 Windows 默认值。

-a (或) -add | 添加一个条目。

-d (或) -del | 删除一个条目。

-add -current | 强制将条目添加到当前用户路径。

-add -local | 强制将条目添加到本地机器路径。

示例:

PATHS -l [+] 索引所有条目。

PATHS -a "C:\Folder" [+] 将一个条目添加到本地路径。

PATHS -a current "C:\Folder" [+] 将一个条目添加到当前用户路径。

PATHS -d "3" [+] 删除索引列表中的第三个条目。

PATHS -d "C:\Folder" [+] 删除一个条目。

PATHS.RB

require 'win32/registry'
require 'rainbow'

# PATHS v0.1
#
# By Elektro H@cker


# Description:
# -----------
# This is a tool to manage the windows PATH enviroment.


exit if Object.const_defined?(:Ocra)


def logo()
  print "
   PATHS v0.1

   By Elektro H@cker

".foreground(:white)
end


def help()
  print '

   Options:

   /? (or) -help  | Show this info.

   -l (or) -list  | List the entries.

   -c (or) -clean | Clean duplicates and invalid directories in the paths.

   -r (or) -reset | Reset the paths to the Windows defaults.

   -a (or) -add   | Add a entry.

   -d (or) -del   | Delete a entry.

   -add -current  | Force adding a entry into the current user path.

   -add -local    | Force adding a entry into the local machine path.



   Examples:

   PATHS -l
   [+] Indexes all the entries.

   PATHS -a "C:\Folder"
   [+] Adds a entry into the local path.

   PATHS -a current "C:\Folder"
   [+] Adds a entry into the current user path.

   PATHS -d "3"
   [+] Deletes the 3rd entry of the indexed list.

   PATHS -d "C:\Folder"
   [+] Deletes a entry.

  '
  Process.exit
end


def error(kind)
  print "[+] ERROR"
  if kind == "pos"      then print "\n    Index #{ARGV[1]} is out of range, only #{$pos} entries.\n" end
  if kind == "notfound" then print "\n    Directory \"#{ARGV[1]}\" not found on PATH.\n" end


  Process.exit
end


def args()
  if ARGV.empty?                                   then get_paths("visible") end
  if ARGV[0] == "/?"    or ARGV[0] =~ /^-help$/i   then help()               end  
  if ARGV[0] =~ /^-l$/i or ARGV[0] =~ /^-list$/i   then get_paths("visible") end
  if ARGV[0] =~ /^-c$/i or ARGV[0] =~ /^-clean$/i  then clean_path()         end    
  if ARGV[0] =~ /^-d$/i or ARGV[0] =~ /^-del$/i    then del_path()           end
  if ARGV[0] =~ /^-a$/i or ARGV[0] =~ /^-add$/i    then add_path()           end
  if ARGV[0] =~ /^-r$/i or ARGV[0] =~ /^-reset$/i  then reset_path()         end
end


def get_paths(visibility)

  $pos = 0

  # HKCU path
  if not visibility == "hidden" then puts "\n   [+] Current User PATH:\n\n" end
  Win32::Registry::HKEY_CURRENT_USER.open('Environment') do |reg|
    for dir in reg['Path', Win32::Registry::REG_SZ].split(";").sort do
      $pos = $pos+1
      dir = dir.gsub(/^PATH=/, "")
      instance_variable_set "@_#{$pos}", dir + "?CURRENT_USER"
      if not File.directory? dir then invalid = "(Directory doesn't exist)".foreground(:red).bright else invalid ="" end
      if not visibility == "hidden"
        if $pos < 10 then puts "    #{$pos.to_s} = #{dir} #{invalid}" else puts "    #{$pos.to_s}= #{dir} #{invalid}"end
      end
    end
  end

  # HKLM path
  if not visibility == "hidden" then puts "\n\n   [+] Local Machine PATH:\n\n" end
  Win32::Registry::HKEY_LOCAL_MACHINE.open('SYSTEM\CurrentControlSet\Control\Session Manager\Environment') do |reg|
    for dir in reg['Path', Win32::Registry::REG_SZ].split(";").sort do
      $pos = $pos+1
      dir = dir.gsub(/^PATH=/, "")
      instance_variable_set "@_#{$pos}", dir + "?LOCAL_MACHINE"
      if not File.directory? dir then invalid = "(Directory doesn't exist)".foreground(:red).bright else invalid ="" end
      if not visibility == "hidden"
        if $pos < 10 then puts "    #{$pos.to_s} = #{dir} #{invalid}" else puts "    #{$pos.to_s}= #{dir} #{invalid}"end
      end
    end
  end
  if not visibility == "hidden" then Process.exit end
  $max_pos = $pos

end


def add_path()

  if ARGV[1] =~ /^-current$/ then key = "current" else key = "local" end

  # HKCU path
  if key == "current"
    Win32::Registry::HKEY_CURRENT_USER.open('Environment', Win32::Registry::KEY_ALL_ACCESS) do |reg|
      value = reg['Path']
      reg.write('Path', Win32::Registry::REG_SZ, "#{value};#{ARGV.last}")
      puts "[+] Entry added in User PATH: #{ARGV.last}"
    end
  end

  # HKLM path
  if key == "local"
    Win32::Registry::HKEY_LOCAL_MACHINE.open('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', Win32::Registry::KEY_ALL_ACCESS) do |reg|
      value = reg['Path']
      reg.write('Path', Win32::Registry::REG_SZ, "#{value};#{ARGV.last}")
      puts "[+] Entry added in Local PATH: #{ARGV.last}"
    end
  end

end


def del_path()

    get_paths("hidden")
    final_path = ""
    found      = 0
    notfound   = 0

  if ARGV[1] =~ /^[1-9]+$/

    choose     = instance_variable_get "@_#{ARGV[1]}"

    if ARGV[1].to_i > $max_pos.to_i then error("pos") end

    # HKCU PATH index deletion
    if choose["?CURRENT_USER"]
      Win32::Registry::HKEY_CURRENT_USER.open('Environment', Win32::Registry::KEY_ALL_ACCESS) do |reg|
        value = reg['Path']
        for dir in reg['Path', Win32::Registry::REG_SZ].split(";").sort do
          if not dir == choose.split("?").first then final_path << ";" + dir end
        end
        reg.write('Path', Win32::Registry::REG_SZ, final_path[1..-1])
      end
      puts "[+] Entry deleted in User PATH: #{choose.split("?").first}"
    end

    # HKLM PATH index deletion
    if choose["?LOCAL_MACHINE"]
      Win32::Registry::HKEY_LOCAL_MACHINE.open('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', Win32::Registry::KEY_ALL_ACCESS) do |reg|
        value = reg['Path']
        for dir in reg['Path', Win32::Registry::REG_SZ].split(";").sort do
          if not dir == choose.split("?").first then final_path << ";" + dir end
        end
        reg.write('Path', Win32::Registry::REG_SZ, final_path[1..-1])
      end
      puts "[+] Entry deleted in Local PATH: #{choose.split("?").first}"
    end

  elsif

    # HKCU PATH str deletion
      Win32::Registry::HKEY_CURRENT_USER.open('Environment', Win32::Registry::KEY_ALL_ACCESS) do |reg|
        value = reg['Path']
        for dir in reg['Path', Win32::Registry::REG_SZ].split(";").sort do
          if not dir =~ /^#{Regexp.escape(ARGV[1])}$/i then final_path << ";" + dir else found = "yes" end
        end
        reg.write('Path', Win32::Registry::REG_SZ, final_path[1..-1])
        if found == "yes" then puts "[+] Entry deleted in User PATH: #{ARGV[1]}" else notfound = 1 end
      end

    # HKLM PATH str deletion
      final_path = ""
      found = ""
      Win32::Registry::HKEY_LOCAL_MACHINE.open('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', Win32::Registry::KEY_ALL_ACCESS) do |reg|
        value = reg['Path']
        for dir in reg['Path', Win32::Registry::REG_SZ].split(";").sort do
          if not dir =~ /^#{Regexp.escape(ARGV[1])}$/i then final_path << ";" + dir else found = "yes" end
        end
        reg.write('Path', Win32::Registry::REG_SZ, final_path[1..-1])
        if found == "yes" then puts "[+] Entry deleted in Local PATH: #{ARGV[1]}" else notfound = notfound+1 end
        if notfound == 2 then error("notfound") end
      end

    end

end


def reset_path()
  Win32::Registry::HKEY_CURRENT_USER.open('Environment', Win32::Registry::KEY_ALL_ACCESS) do |reg| reg.write('Path', Win32::Registry::REG_SZ, 'C:\Windows;C:\Windows\system32;C:\Windows\System32\Wbem;C:\Windows\syswow64') end
  Win32::Registry::HKEY_LOCAL_MACHINE.open('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', Win32::Registry::KEY_ALL_ACCESS) do |reg| reg.write('Path', Win32::Registry::REG_SZ, 'C:\Windows;C:\Windows\system32;C:\Windows\System32\Wbem;C:\Windows\syswow64') end
  puts "[+] PATH restored to Windows defaults."
end


def clean_path()

  puts "\n[+] Searching invalid or duplicated entries in the PATH...\n\n"

  # HKCU PATH
  final_path = ""
  Win32::Registry::HKEY_CURRENT_USER.open('Environment', Win32::Registry::KEY_ALL_ACCESS) do |reg|
    value = reg['Path']
    for dir in reg['Path', Win32::Registry::REG_SZ].split(";").sort do
      if File.directory? dir and not final_path[/#{Regexp.escape(dir)}$/i] then final_path << ";" + dir else puts "[+] Entry deleted in User PATH: #{dir}" end
    end
    reg.write('Path', Win32::Registry::REG_SZ, final_path[1..-1])
  end

  # HKLM PATH
  final_path = ""
  Win32::Registry::HKEY_LOCAL_MACHINE.open('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', Win32::Registry::KEY_ALL_ACCESS) do |reg|
    value = reg['Path']
    for dir in reg['Path', Win32::Registry::REG_SZ].split(";").sort do
      if File.directory? dir and not final_path[/#{Regexp.escape(dir)}$/i] then final_path << ";" + dir else puts "[+] Entry deleted in Local PATH: #{dir}" end
    end
    reg.write('Path', Win32::Registry::REG_SZ, final_path[1..-1])
  end

  puts "\n[+] PATH is cleaned.\n\n"

end


logo()
args()


Process.exit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接