Запустите функцию/задачу Powershell в фоновом режиме

У меня есть функция, которая позволяет мне записывать путь к файлам в текстовый файл в зависимости от вашего ввода. Звучит запутанно, но я не знаю, как лучше выразиться, поэтому вот функция:

Function writeAllPaths([string]$fromFolder,[string]$filter,[string]$printfile) {
    Get-ChildItem -Path $fromFolder -Recurse $filter | Select-Object -Property FullName > $printfile
}

Первый аргумент — папка, из которой вы начинаете поиск.
Второй аргумент — фильтр. Например, *.zip выведет список всех zip-файлов. Третий аргумент, вы должны указать, где будет находиться текстовый файл.

Пример использования: writeAllPaths c:\ *.zip c:\allZips.txt

Дело в том, что когда я это делаю, Powershell не будет принимать команды, пока это не будет сделано. Что не очень продуктивно. Есть ли способ запустить это в фоновом режиме при запуске. И желательно, дайте небольшое сообщение, когда это будет сделано. Я мог бы открыть любой файл, который создается в середине процесса...

Кроме того, у меня Windows 7, поэтому я предполагаю, что у меня Powershell 2.0.

Да, я не уверен в этом :p

РЕДАКТИРОВАТЬ:

Я использовал Start-Job, как было предложено, следующим образом:

Function writeAllPaths([string]$fromFolder,[string]$filter,[string]$printfile) {
  Start-Job -ScriptBlock {Get-ChildItem -Path $fromFolder -Recurse $filter | Select-Object -Property FullName > $printfile}
}

Однако файл не создается. Старая функция создает файл.

EDIT2: было бы предпочтительнее иметь эту функцию в моем профиле Powershell. Таким образом, я могу выполнять его, когда захочу, вместо того, чтобы загружать конкретный файл ps1 каждый раз при загрузке Powershell.

Дополнительную информацию о профиле Powershell можно найти здесь. Вы можете вызвать свой собственный профиль, набрав: notepad $profile


person KdgDev    schedule 07.11.2009    source источник


Ответы (2)


В новой области, которую вы создаете для фонового задания, ваши параметры, определенные для вашей функции WriteAllPaths, не определены. Попробуйте это, и вы увидите, что это не так:

Function writeAllPaths([string]$fromFolder,[string]$filter,[string]$printfile) 
{    
    Start-Job { "$fromFolder, $filter, $printFile" }
}

$job = WriteAllPaths .\Downloads *.zip zips.txt
Wait-Job $job
Receive-Job $job

, ,

Попробуйте это вместо этого:

Function writeAllPaths([string]$fromFolder, [string]$filter, [string]$printfile) 
{    
    Start-Job {param($fromFolder,$filter,$printfile) 
               "$fromFolder, $filter, $printfile" } `
               -ArgumentList $fromFolder,$filter,$printfile
}

$job = WriteAllPaths .\Downloads *.zip z.txt
Wait-Job $job
Receive-Job $job

.\Downloads, *.zip, z.txt

Теперь вы видите свой вывод, потому что мы передали параметры в блок сценария через -ArgumentList. Я бы порекомендовал функцию, которая может дополнительно использовать фоновое задание. Просто вставьте это определение функции в свой профиль, и все готово:

function WriteAllPaths([string]$FromFolder, [string]$Filter, 
                       [string]$Printfile, [switch]$AsJob) 
{
    if (![IO.Path]::IsPathRooted($FromFolder)) {
        $FromFolder = Join-Path $Pwd $FromFolder
    }
    if (![IO.Path]::IsPathRooted($PrintFile)) {
        $PrintFile = Join-Path $Pwd $PrintFile
    }

    $sb = {
        param($FromFolder, $Filter, $Printfile)
        Get-ChildItem $FromFolder -r $filter | Select FullName > $PrintFile
    }

    if ($AsJob) {
        Start-Job $sb -ArgumentList $FromFolder,$Filter,$PrintFile
    }
    else {
        & $sb $FromFolder $Filter $PrintFile        
    }
}

Протестируйте функцию (синхронно) следующим образом:

$job = WriteAllPaths Downloads *.zip z.txt -AsJob
Wait-Job $job
Receive-Job $job

Обратите внимание, что я проверяю, является ли путь корневым, и если нет, я добавляю текущий каталог. Я делаю это, потому что начальный каталог фонового задания не всегда совпадает с тем, откуда вы запускали Start-Job.

person Keith Hill    schedule 07.11.2009
comment
А предположим, я хотел бы иметь эту функцию в моем профиле Powershell? - person KdgDev; 07.11.2009
comment
Я обновил пост для этого. Обратите внимание на добавление параметра -AsJob. - person Keith Hill; 07.11.2009
comment
Я должен просто вставить это определение функции в ваш профиль, и все готово. А как же 3-я последняя строчка. Есть ссылка на WriteAllPaths.ps1, которой не существует. Кроме того, если я просто вставлю этот код в свой профиль, каков будет эффект этих последних 3 строк. Они не включены в функцию, а существуют непосредственно в профиле. Поэтому каждый раз, когда Powershell запускается, он будет пытаться их выполнить. - person KdgDev; 08.11.2009
comment
Просто вставьте функцию. Эти три строки просто показывают, как выполнять синхронно. Обычно вы не выполняете команду Wait-Job, так как хотите выполнять другую работу, а не ждать завершения задания. - person Keith Hill; 09.11.2009

Какая версия пауэршелла? Я думаю, что в Powershell 2.0 вы можете использовать фоновые задания для этого Start-Job.

Запускает фоновое задание Windows PowerShell.

person jitter    schedule 07.11.2009
comment
У меня Windows 7 Ultimate, так что я предполагаю, что 2.0 - person KdgDev; 07.11.2009
comment
Хорошо, тогда прочитайте PsJob, Start/Stop/Wait/Get/Remove/Receive-Job - person jitter; 07.11.2009