Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esperecyan/51195c40847eb143bdbeb9d85476be8c to your computer and use it in GitHub Desktop.
Save esperecyan/51195c40847eb143bdbeb9d85476be8c to your computer and use it in GitHub Desktop.
※2020年3月に発生した本不具合はすでに修正されているようです。(2022-05-05 SteamVR 1.21.12で確認) 『restore-defualt-audio-after-steamvr.ps1.jse』 SteamVR終了時に、既定のデバイスを復元します。
#@~^AQAAAA==~IAAAAA==^#~@ function toPSString(str) { return "'" + str.replace(/%/g, '"%"').replace(/'/g, "''") + "'"; } /* -*- mode: powershell;-*-
<#*/ var command = 'param($AudioOutput, $AudioInput, $IntervalSeconds = 10)'
+ '; $_PSCommandPath = ' + toPSString(WSH.ScriptFullName)
+ '; Invoke-Expression (Get-Content ' + toPSString(WSH.ScriptFullName) + ' -Encoding UTF8 -Raw)';
var namePattern = /^-(?!(?:b(?:and|or|xor|not)|sh[lr]|[ic]?(?:eq|ne|gt|ge|lt|le|(?:not)?(?:like|match|contains|in)|replace|split)|join|is(?:not)?|as|and|or|not|f)$)[0-9a-z]+$/i;
var args = ''; for (var i = 0; i < WSH.Arguments.Length; i++) {
var arg = WSH.Arguments(i); args += ' ' + (namePattern.test(arg) ? arg : toPSString(arg)); }
WSH.CreateObject('WScript.Shell').Run('PowerShell -Command &{' + command + '}' + args, 0); /*#>
<#
.SYNOPSIS
SteamVR終了時に、既定のデバイスを復元します。
.DESCRIPTION
あらかじめ nircmd.exe をパスの通った場所へ置いておく必要があります。
https://www.nirsoft.net/utils/nircmd.html
ダブルクリックで起動し、通知領域 (タスクトレイ) のアイコンから終了できます。
既定のデバイス名が「スピーカー / ヘッドホン」と「マイク」でなければ、コマンドラインオプションの指定が必要です。
SPDX-License-Identifier: MPL-2.0
Version: 1.0.0
Author: 100の人
配布元: https://gist.github.com/esperecyan
【更新履歴】
v1.0.1 (2022-05-05)
コマンドラインオプション名が正しくは「AudioOutput」「AudioInput」であったところを「Output」「Input」と説明していたのを修正。
v1.0.0 (2020-03-25)
公開
.PARAMETER AudioOutput
既定の再生デバイス名。既定値は「スピーカー / ヘッドホン」。
.PARAMETER AudioInput
既定の録音デバイス名。既定値は「マイク」。
.PARAMETER IntervalSeconds
プロセスのチェック間隔。1以上の秒数。既定値は10秒。
#>
using namespace System.IO
using namespace System.Linq
using namespace System.Drawing
using namespace System.Windows.Forms
using namespace System.Management.Automation
using namespace Esperecyan.Net
$STEAMVR_PROCESS_PATH = 'C:\Program Files (x86)\Steam\steamapps\common\SteamVR\bin\win64\vrmonitor.exe'
$STEAMVR_PROCESS_NAME = [Path]::GetFileNameWithoutExtension($STEAMVR_PROCESS_PATH)
if (!$AudioOutput) {
$AudioOutput = "スピーカー / ヘッドホン"
}
if (!$AudioInput) {
$AudioInput = "マイク"
}
<#
.SYNOPSIS
例外の詳細を警告ダイアログで表示し、スクリプトを終了します。
.PARAMETER ErrorRecord
catch { } 内の $_ 。
#>
function Exit-Script([ErrorRecord]$ErrorRecord)
{
[MessageBox]::Show(
"例外が発生しました。スクリプトを終了します。`n`n【例外メッセージ】(Ctrl+Cでコピー可能)`n$('-' * 78)`n" `
+ "$($ErrorRecord | Out-String)`nScriptStackTrace:`n$($ErrorRecord.ScriptStackTrace)",
$SCRIPT_NAME,
[MessageBoxButtons]::OK,
[MessageBoxIcon]::Error,
[MessageBoxDefaultButton]::Button1,
[MessageBoxOptions]::DefaultDesktopOnly
) | Out-Null
try {
$notifyIcon.Visible = $false
} catch {
}
[Environment]::Exit(0)
}
try { Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop';
Add-Type -AssemblyName @('System.Drawing', 'System.Windows.Forms')
Add-Type -Name ('ShellAPI') -Namespace 'Esperecyan.Net' -MemberDefinition @('
[DllImport("shell32.dll")]
public static extern int ExtractIconEx(
string lpszFile,
int nIconIndex,
out System.IntPtr phiconLarge,
out System.IntPtr phiconSmall,
int nIcons
);
')
<#
.SYNOPSIS
ファイルからアイコンを取得します。
.PARAMETER Path
「shell32.dll」のようなファイルパス。
.PARAMETER Index
0から始まる、ファイル内のアイコンのインデックス。
.OUTPUTS
アイコン。
#>
function Get-IconFromFile
{
[OutputType([Icon])]
param([Parameter(Mandatory)][string]$Path, [Parameter(Mandatory)][int]$Index)
$phiconLarge = New-Object IntPtr
$phiconSmall = New-Object IntPtr
[ShellAPI]::ExtractIconEx($Path, $Index, [ref]$phiconLarge, [ref]$phiconSmall, 1) | Out-Null
[Icon]::FromHandle($phiconSmall).Dispose()
$icon = [Icon]::FromHandle($phiconLarge)
$icon.Dispose()
return $icon
}
$SCRIPT_NAME = 'restore-defualt-audio-after-steamvr.ps1.jse'
$bitmap = New-Object Bitmap(16, 16)
$graphics = [Graphics]::FromImage($bitmap)
$graphics.DrawIcon((Get-IconFromFile -Path $STEAMVR_PROCESS_PATH -Index 0), (New-Object Rectangle(0, 0, 12, 12)))
$graphics.DrawIcon((Get-IconFromFile -Path 'SndVol.exe' -Index 1), (New-Object Rectangle(6, 6, 10, 10)))
$graphics.Dispose()
$ICON = [Icon]::FromHandle($bitmap.GetHicon())
$bitmap.Dispose()
<#
.SYNOPSIS
イベントを妨げない状態で、スクリプトを終了させずに待機します。
#>
function Wait-Exit
{
$form = New-Object Form
$form.Text = $SCRIPT_NAME
$form.ShowInTaskbar = $false
$form.StartPosition = [FormStartPosition]::Manual
$form.Location = New-Object Point([int]::MaxValue, [int]::MaxValue)
$form.Add_Closed($exit)
$form.ShowDialog()
}
# $confirmProcesses 内から値を書き替えられるようにするため配列
$previousSteamVRActive = @($false)
$exit = {
$timer.Stop()
& $confirmProcesses
$notifyIcon.Visible = $false
[Environment]::Exit(0)
}
$notifyIcon = New-Object NotifyIcon
$notifyIcon.Icon = $ICON
$notifyIcon.Text = $SCRIPT_NAME
$contextMenu = New-Object ContextMenuStrip
$contextMenu.Items.Add((New-Object ToolStripMenuItem('終了', $null, { & $exit })))
$notifyIcon.ContextMenuStrip = $contextMenu
$notifyIcon.Visible = $true
$confirmProcesses = {
try {
$steamVRActive = $false
foreach ($process in (Get-Process)) {
if ($process.Name -eq $STEAMVR_PROCESS_NAME) {
$steamVRActive = $true
break
}
}
if ($previousSteamVRActive[0] -and !$steamVRActive) {
# SteamVRが終了した直後なら
nircmd setdefaultsounddevice $AudioOutput 1
nircmd setdefaultsounddevice $AudioInput 1
}
$previousSteamVRActive[0] = $steamVRActive
} catch {
Exit-Script -ErrorRecord $_
}
}
$timer = New-Object Timer
$timer.Interval = [int]$IntervalSeconds * 1000
$timer.Add_Tick($confirmProcesses)
$timer.Start()
# 待機
Wait-Exit
} catch {
Exit-Script -ErrorRecord $_
} # */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment