workon命令在Windows PowerShell中无法激活virtualenv

时间:2016-08-14 17:03:54

标签: python-3.x powershell virtualenvwrapper

我已经安装了virtualenvwrapper-win,当我尝试这个命令时

workon <envname>

在CMD中,它可以工作,但不能在Windows PowerShell中使用。

在Windows PowerShell中,我必须执行Scripts\activate.ps1,然后在提示符之前获取envname。

请告诉我如何在PowerShell中使用workon命令?

6 个答案:

答案 0 :(得分:10)

workon是一个批处理脚本。如果您从PowerShell运行它,它将在新的CMD子进程中启动,在那里执行它的操作,然后退出并返回到PowerShell提示符。由于子进程无法修改其父进程,因此当您返回PowerShell时,会丢失workon.bat所做的所有修改。

您基本上有两个选择:

  • 在PowerShell中重写workon.bat(以及它调用的其他批处理脚本)。

  • 在不退出CMD子进程的情况下运行workon.bat

    & cmd /k workon <envname>
    

    如果您只想要一个可以直接从PowerShell调用的快捷方式workon,您可以将该命令行包装在一个函数中,并将函数定义放入PowerShell配置文件中:

    function workon($environment) {
      & cmd /k workon.bat $environment
    }
    

    在此处使用带扩展名的scriptname以避免无限递归。

答案 1 :(得分:4)

Ansgar Wiechers的答案在技术上有效,但它使用cmd,这意味着您基本上使用PowerShell中的cmd提示,并且您将失去PowerShell提供的其他功能。您可以将上述功能修改为以下内容:

function workon ($env) { & .\Envs\$env\Scripts\activate.ps1 }

这将允许您继续在虚拟环境中使用PowerShell命令(在ls等cmd中不起作用)

这也假定您的环境保存在。\ Envs中。如果它们在其他地方,则相应地调整函数中的路径。

此外,如果您是Windows用户(像我一样),并且需要帮助来确定该功能的放置位置以及打开PowerShell时如何加载它。以下是一些帮助我的其他资源:

背景:

How to Write a PowerShell Script Module

Importing a PowerShell Module

如何让PowerShell在启动时自动加载模块:

How to Create a PowerShell Profile

Start PowerShell with modules loaded

答案 2 :(得分:1)

有一个更简单的解决方案!只需转到存在workon.bat文件的python脚本文件夹,然后创建一个名为workon.ps1的新文件,并将以下行添加到其中

iex ("~\Envs\" + $args[0] + "\Scripts\activate.ps1")

如果您将virtualenvs存储在其他地方并且还将执行策略设置为允许脚本,则许多人需要适当地更改此设置。现在您可以在cmd和powershell中使用workon,因为ps1将在powershell中执行,而bat将在cmd中执行。

您还可以查看virtualenvwrapper-win的my fork(完全披露:我是powershell部分的作者),其中包含一些针对PowerShell的重写脚本,并且应该同时适用于CMD和PowerShell。如果要复制粘贴,请创建两个文件workon.ps和`cdproject。

workon.ps1

if (-not (Test-Path env:WORKON_HOME))
{
    $WORKON_HOME = '~\Envs'
} else {
    $WORKON_HOME = ($env:WORKON_HOME).Replace('"','')
}

if (-not (Test-Path env:VIRTUALENVWRAPPER_PROJECT_FILENAME)) {
    $VIRTUALENVWRAPPER_PROJECT_FILENAME = '.project'
} else {
    $VIRTUALENVWRAPPER_PROJECT_FILENAME = ($env:VIRTUALENVWRAPPER_PROJECT_FILENAME).Replace('"','')
}

if ($args.length -eq 0) {
    echo "Pass a name to activate one of the following virtualenvs:"
    echo ==============================================================================
    (Get-ChildItem -Path $WORKON_HOME).Name
    return
}

$VENV = $args[0]

if (!(Test-Path -Path ("$($WORKON_HOME)\$($VENV)"))) {
    echo ("virtualenv $($VENV) does not exist")
    echo "Create it with 'mkvirtualenv $($VENV)'"
    return
}

if (!(Test-Path -Path ("$($WORKON_HOME)\$($VENV)\Scripts\activate.ps1") ))  {
    echo "$($WORKON_HOME)$($VENV)"
    echo "doesn't contain a virtualenv (yet)."
    echo "Create it with 'mkvirtualenv $($VENV)'"
    return
}

iex ("$($WORKON_HOME)\$($VENV)\Scripts\activate.ps1")

if (Test-Path -Path ("$($WORKON_HOME)\$($VENV)\$($VIRTUALENVWRAPPER_PROJECT_FILENAME)")) {
    iex "cdproject"
}

cdproject.ps1

function Show-Usage {
    echo ""
    echo  "switches to the project dir of the activated virtualenv"
}

if (-not (Test-Path env:VIRTUAL_ENV)) {
    echo ""
    echo "a virtualenv must be activated"
    Show-Usage
    return
}

if (-not (Test-Path env:VIRTUALENVWRAPPER_PROJECT_FILENAME)) {
    $VIRTUALENVWRAPPER_PROJECT_FILENAME = '.project'
} else {
    $VIRTUALENVWRAPPER_PROJECT_FILENAME = ($env:VIRTUALENVWRAPPER_PROJECT_FILENAME).Replace('"','')
}

if (-not (Test-Path "$($env:VIRTUAL_ENV)\$($VIRTUALENVWRAPPER_PROJECT_FILENAME)")) {
    echo ""
    echo "No project directory found for current virtualenv"
    Show-Usage
    return
}


$ENVPRJDIR = Get-Content "$($env:VIRTUAL_ENV)\$($VIRTUALENVWRAPPER_PROJECT_FILENAME)" -First 1

# If path extracted from file contains env variables, the system will not find the path.
# TODO: Add this functionality

cd $ENVPRJDIR

答案 3 :(得分:0)

我有类似的问题。 请按照上述某些步骤对其进行修复。

在此处列出:

  • 同时安装VirtualEnv和VirtualEnvWrapper-win
  • 将ExecutionPolicy设置为RemoteSigned Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
  • 将环境路径“ WORKON”添加到“ envs目录”
  • 现在尝试使用“ workon”命令

答案 4 :(得分:0)

只需在powershell上键入“ CMD”,它将启动cmd然后工作

答案 5 :(得分:0)

我在Windows10的Powershell中使用virtualenvwrapper遇到了相同的问题。我喜欢@Erock给出的答案,但这种方式使workon过于混乱,以至于在没有参数的情况下运行workon会引发错误,而不是显示可用的环境。这是我的解决方法。

function workon ($env) {
    if ($env) {
        & $env:WORKON_HOME\$env\Scripts\activate.ps1
    } else {
        Write-Host "Pass a name to activate one of the following virtualenvs:"
        Write-Host" ================================================================"
        Get-ChildItem $env:WORKON_HOME -Name
    }
}

请注意,我已经设置了WORKON_HOME envrionment变量。