Last active
May 5, 2022 00:49
-
-
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終了時に、既定のデバイスを復元します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#@~^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