【问题标题】:Set path where PowerShell tries to find applications设置 PowerShell 尝试查找应用程序的路径
【发布时间】:2020-03-13 23:35:41
【问题描述】:

几个月前,在 .NET 开发机器上设置了 Sqlite3,以开发一个应用程序,该应用程序将运行 PowerShell 脚本来构建/重建离线数据库。在开发机器上,一切正常。在用户机器上进行测试的部署遇到了障碍。

Sqlite3 安装到 C:\sqlite3 文件夹。 PowerShell 脚本无法找到指向位于应用程序文件夹中的“sqlite3.exe”的“sqlite3”命令。在 .NET 中使用 PowerShell 对我来说是新事物,我无法回忆几个月前设置 PowerShell 以运行 Sqlite3 的步骤。

在开发系统上,通过PowerShell显示如下:

在用户机器上,我无法确定此命令是如何设置的,因此无论当前目录路径如何,PowerShell 都能够识别该命令。

任何智慧都值得赞赏....谢谢。

【问题讨论】:

  • 始终完全限定您的路径。 & 'C:\sqlite3\sqlite3.exe' args...
  • 对合格路径进行广泛的陈述与手头的问题无关。问题是如何配置 PowerShell 以便无论当前目录路径如何都能识别命令......如图所示。
  • 完全限定您的路径,正如 TheIncorrigible 建议的那样,将配置 Powershell 以始终识别该命令,而不管当前目录路径如何。
  • Sqlite3 在该图中出于某种原因是一个函数。

标签: powershell


【解决方案1】:

当 PowerShell 查找由仅文件名指定的外部程序时,例如 sqlite3.exe 在您的情况下:

  • 它会在$env:Path 中列出的目录中查找,即Path 环境变量,正如通过注册表预先配置的那样。

    • 注意:cmd.exe 也是这样做的,只是它首先在 current 目录中查找,PowerShell 在设计上出于安全原因不这样做。
  • 它调用/报告该名称的第一个可执行文件。

要通过Get-Command 进行检查,您可以通过-All 开关来查看$env:Path 列出的目录中是否存在多个 同名的可执行文件,但对于调用 它总是第一个被使用。

因此,您有 3 个选择:

  • 在调用您的脚本之前,持续修改目标机器上的Path 环境变量以包含C:\sqlite3 目录。

    • 以交互方式,您可以使用控制面板(特别是sysdm.cpl,选项卡Advanced)添加到您的Path 变量,无论是在当前用户范围内还是在整个计算机范围内。
    • 如需通过 .NET 进行编程操作,请参阅 this answer(可与 PowerShell remoting 结合以远程执行更改)。
    • 使用reg.exe也是一个选项,它本身支持针对其他机器;但是,在这种情况下,您必须明确定位相关的注册表路径:HKEY_CURRENT_USER\Environment(当前用户)和HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment(本地计算机)。
  • 或者,在您的脚本中

    • 或者:通过其完整路径调用可执行文件,正如TheIncorrigible1 建议的那样:
      C:\sqlite3\sqlite3.exe ...(前置& ,如果路径必须被引用或通过变量指定)。

    • 或者:在调用sqlite3.exe之前将C:\sqlite3添加到Path变量中
      $env:PATH += ';C:\sqlite3'请注意,这个修改后的Path变量将保留对整个 PowerShell 会话(进程)有效,但不会持续

【讨论】:

  • 不错。在我的搜索中添加了“持久性”一词后,我也发现了这一点。另外,我认为 $env:path 是从 Windows 环境变量 PATH 显示的信息,但它们并不相同。在开发机器上,您添加的持久性语句之前已经完成。由于我正在查看 Windows PATH 环境变量,因此没有显示 C:\sqlite3。查看 PowerShell 命令“$env:path”的输出后,我确实看到“C:\sqlite3”已经列出。下一步是在用户的机器上应用你的持久化命令
  • @Galactic:$env:Path 是进程默认看到的注册表中当前用户和本地机器环境变量定义的组合。任何进程都可以修改变量,这意味着从它启动的任何子进程也可以看到修改。当您说 Windows PATH 环境 变量时,您指的是什么?基于注册表的定义?如果是这样,当前用户或本地机器定义?请注意,$env:Path 修改的潜在来源是您的 $PROFILE 文件,例如。
【解决方案2】:

这是我为 jdk 添加路径的脚本:

$CurrentValue = [Environment]::GetEnvironmentVariable('Path', 'Machine')

$list = $currentvalue -split ';'

# delete old one
$list = $list | where { $_ -notlike 'C:\Program Files (x86)\Java\jdk1.8.0_*' }

# add new one
$list = $list + $args[0]

$newvalue = $list -join ';'

[Environment]::SetEnvironmentVariable('Path', $newvalue, 'Machine')

if ( -not $? ) { exit 1 }

【讨论】:

    猜你喜欢
    • 2011-01-30
    • 2012-09-22
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    相关资源
    最近更新 更多