dimayakovlev.ru


Корректное завершение работы плеера iTunes при использовании скробблера из PowerShell

Каждый пользователь плеера iTunes и Microsoft Windows, желающий в реальном времени сохранять свою историю прослушиваний музыкальных треков в базе сервиса Last.fm, сталкивается с проблемой - перед завершением работы плеера выводится уведомление об использовании интерфейса сценариев iTunes с предложением подождать 20 секунд, а после закрытия плеера он автоматически перезапускается. Почему так происходит, как решить эту проблему, расскажу дальше.

Такое поведение iTunes это не ошибка в работе программы и не ошибка в работе операционной системы. Для отправки сервису Last.fm в реальном времени данных о текущем прослушиваемом музыкальном треке, используется клиентская программа, отслеживающая события плеера - скробблер. Скробблер подключается к iTunes через COM-интерфейс, что препятствует корректному завершению работы iTunes. Именно об этом сообщается в уведомлении.

Теперь, зная причину, пользователь может корректно завершить работу iTunes так:

  1. Завершить работу скробблера;
  2. Завершить работу iTunes.

Каждый раз выполнять эти действия вручную не удобно, поэтому предлагаю автоматизировать задачу с использованием сценария PowerShell.

Существуют разные программы для скробблинга, но в примере будет рассматриваться вариант использования официального клиента сервиса Last.fm Last.fm Desktop Scrobbler, работающего с текущей версией плеера iTunes 12.11.4.15.

# Список имён процессов, подлежащих завершению
$processList = @('Last.fm Desktop Scrobbler', 'iTunes')
# Список состояния процессов
$processState = @{}
# Время ожидания завершения процесса в миллисекундах
# 1 секунда = 1000 миллисекунд
$wait = 4000
foreach ($name in $processList) {
  $proc = Get-Process -Name $name -ErrorAction SilentlyContinue
  if ($proc) {
    Write-Output "$name Is Running. Try To Close"
    # Отправка сообщения о закрытии главного окна
    $sendCloseMessage = $proc.CloseMainWindow()
    if (-Not $sendCloseMessage) {
      $proc.Kill()
    }
    # Ожидание завершения процесса с заданным временем в миллисекундах
    $closed = $proc.WaitForExit($wait)
    # Для бесконечного ожидания используется значение -1
    # $closed = $proc.WaitForExit(-1)
    $processState[$name] = $closed
    if ($closed) {
      Write-Output "$name Closed Successfully"
    } else {
      Write-Output "$name Cannot Be Closed"
    }
  } else {
    $processState[$name] = $false
    Write-Output "$name Not Running"
  }
  Remove-Variable proc
}
# Перезапуск Last.fm Desktop Scrobbler
if ($processState[$processList[0]] -eq $true) {
  Start-Process -FilePath "${Env:ProgramFiles(x86)}\Last.fm\Last.fm Desktop Scrobbler\Last.fm Desktop Scrobbler.exe"
  If ((Get-Process -Name $processList[0] -ErrorAction SilentlyContinue)) {
      Write-Host "$($processList[0]) Is Restarted"
  } Else {
      Write-Host "$($processList[0]) Is Not Restarted. Try To Run It Manualy"
  }
}

Сохранив код сценария в файл \Documents\WindowsPowerShell\Scripts\Stop-iTunes.ps1, можно создать ярлык для его быстрого запуска. При создании ярлыка задайте следующую цель: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File %HOMEDRIVE%%HOMEPATH%"\Documents\WindowsPowerShell\Scripts\Stop-iTunes.ps1".

Если скробблер не включён а автозагрузку операционной системы, вы можете забыть запустить его вручную перед началом использования iTunes. Чтобы не потерять статистику прослушиваний, может быть полезен сценарий, автоматически запускающий скробблер перед запуском плеера. Взяв за пример приведённый код, написание такого сценария не должно вызвать затруднений.

Если вы не используете скробблер, но всё-равно сталкиваетесь с рассмотренной проблемой при закрытии iTunes, ищите процесс, который использует COM-интерфейс iTunes и завершайте его перед завершением работы iTunes.