2016-08-14 365 views
2

我已经安装了virtualenvwrapper赢,当我尝试这个命令workon命令不会在Windows PowerShell中工作,以激活的virtualenv

workon <envname> 

在CMD它的工作原理,但不是在Windows PowerShell中。

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

您能否让我知道如何让workon命令在PowerShell中工作?

回答

5

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

你基本上有两种选择:

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

  • 运行workon.bat,而不脱离CMD子进程退出:

    & cmd /k workon <envname> 
    

    如果你只是想要一个快捷方式workon,你可以从PowerShell中直接调用你可以用该命令行中的函数,并把函数定义插入到PowerShell配置文件中:

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

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

+0

这个功能是方便的,谢谢! – Patrick

+0

第二种选择是不正确的,因为它不再使用PowerShell。首先可以使用cmd! – PulseJet

1

通过安斯加尔Wiechers答案技术上的作品,但它使用cmd你基本上是用在PowerShell的命令提示符,你失去通过PowerShell中提供的附加功能,这意味着。您可以修改上面的函数以下:

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

这将允许你继续使用PowerShell命令(不在cmd中工作,如ls)在虚拟环境中

这也假定您的环境保存在。\ 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

0

有一个更简单的解决方案!只要到你的Python脚本文件夹,其中workon.bat文件存在并创建一个名为workon.ps1一个新的文件,并添加下面一行到它

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

你,如果你保存你virtualenvs其他地方许多需要适当改变这一点,还要设置执行策略以允许脚本。现在,您可以在cmd和PowerShell中使用workon,因为ps1将在cmd中以powershell和bat执行。

您还可以查看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 
+0

我觉得输入'&cmd/k workon '就像Ansgar Wiechers说的那样比你提议的要简单得多 –

+0

@RonG我认为答案的第二部分是错误的*,因为它涉及切换到cmd,击败整点使用PowerShell。我也可以建议使用cmd来代替,这会为我开箱即用。 – PulseJet