Menghidupkan / mematikan radio / adaptor Bluetooth dari cmd / PowerShell di Windows 10

28

Tugas yang sangat sederhana, bisa dikatakan, dan saya belum menemukan solusi yang memuaskan. Apa yang saya coba (dengan musik diputar melalui speaker yang terhubung Bluetooth untuk benar-benar mengetahui keadaan radio):

  • menggunakan devcon sebagai admin: devcon disable USB\VID_8087&PID_07DC&REV_0001(yang merupakan HW ID adaptor Bluetooth saya) ... memerlukan reboot untuk berfungsi ...
  • menggunakan powershell sebagai admin: Disable-NetAdapter "Bluetooth Network Connection 3"(yang merupakan terjemahan dari nama adaptor Bluetooth saya) ... itu menonaktifkan driver PAN, tetapi speaker Bluetooth terus memutar musik ...
  • menggunakan internet sebagai admin: net stop bthserv... sebenarnya tidak mematikan radio (speaker BT terus memutar musik)
  • menggunakan .NET: Halaman paling relevan di MSDN tidak mengatakan sepatah kata pun tentang menghidupkan / mematikan adaptor.
  • menggunakan explorer: ms-settings:bluetoothatau explorer.exe %LocalAppData%\Packages\windows.immersivecontrolpanel_cw5n1h2txyewy\LocalState\Indexed\Settings\cs-CZ\AAA_SettingsPagePCSystemBluetooth.settingcontent-ms... membuka panel pengaturan Bluetooth, tetapi saya masih harus mengklik sakelar

Saya tidak percaya Microsoft akan begitu bodoh untuk tidak memberikan perintah seperti itu ...

Martin Pecka
sumber
Bagaimana kamu memainkan musik?
harrymc
Menggunakan Winamp :)
Martin Pecka
Apakah membunuh Winamp menghentikan musik?
harrymc
Tentu saja, mengapa tidak? Tetapi pertanyaannya bukan tentang menghentikan pemutaran musik, ini tentang kontrol radio BT.
Martin Pecka
1
@harrymc Baca pertanyaannya. Pemutaran musik hanyalah cara saya mendeteksi apakah koneksi Bluetooth hidup atau tidak. Yang saya benar-benar tertarik adalah cara untuk menonaktifkan / mengaktifkan adaptor Bluetooth.
Martin Pecka

Jawaban:

21

Ini menantang karena interoperasi yang diperlukan dengan WinRT, tetapi dimungkinkan dalam PowerShell murni:

[CmdletBinding()] Param (
    [Parameter(Mandatory=$true)][ValidateSet('Off', 'On')][string]$BluetoothStatus
)
If ((Get-Service bthserv).Status -eq 'Stopped') { Start-Service bthserv }
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$asTaskGeneric = ([System.WindowsRuntimeSystemExtensions].GetMethods() | ? { $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' })[0]
Function Await($WinRtTask, $ResultType) {
    $asTask = $asTaskGeneric.MakeGenericMethod($ResultType)
    $netTask = $asTask.Invoke($null, @($WinRtTask))
    $netTask.Wait(-1) | Out-Null
    $netTask.Result
}
[Windows.Devices.Radios.Radio,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null
[Windows.Devices.Radios.RadioAccessStatus,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null
Await ([Windows.Devices.Radios.Radio]::RequestAccessAsync()) ([Windows.Devices.Radios.RadioAccessStatus]) | Out-Null
$radios = Await ([Windows.Devices.Radios.Radio]::GetRadiosAsync()) ([System.Collections.Generic.IReadOnlyList[Windows.Devices.Radios.Radio]])
$bluetooth = $radios | ? { $_.Kind -eq 'Bluetooth' }
[Windows.Devices.Radios.RadioState,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null
Await ($bluetooth.SetStateAsync($BluetoothStatus)) ([Windows.Devices.Radios.RadioAccessStatus]) | Out-Null

Untuk menggunakannya, simpan itu file PS1, mis bluetooth.ps1. Jika Anda belum melakukannya, ikuti instruksi di bagian Skrip yang Mengaktifkan wiki tag PowerShell untuk mengaktifkan eksekusi skrip di sistem Anda. Kemudian Anda dapat menjalankannya dari prompt PowerShell seperti ini:

.\bluetooth.ps1 -BluetoothStatus On

Untuk mematikan Bluetooth, lewati Offsaja.

Untuk menjalankannya dari file batch:

powershell -command .\bluetooth.ps1 -BluetoothStatus On

Peringatan: Jika Layanan Dukungan Bluetooth tidak berjalan, skrip mencoba untuk memulainya karena jika tidak, WinRT tidak akan melihat radio Bluetooth. Sayangnya, layanan tidak dapat dimulai jika skrip tidak berjalan sebagai administrator. Untuk membuatnya tidak perlu, Anda dapat mengubah jenis startup layanan itu menjadi otomatis.

Sekarang untuk penjelasan. Tiga baris pertama menetapkan parameter yang diambil skrip. Sebelum memulai dengan sungguh-sungguh, kami memastikan Layanan Dukungan Bluetooth berjalan dan memulainya jika tidak. Kami kemudian memuat System.Runtime.WindowsRuntimeperakitan sehingga kami dapat menggunakan WindowsRuntimeSystemExtensions.AsTaskmetode untuk mengkonversi tugas-tugas gaya WinRT (yang .NET / PowerShell tidak mengerti) ke .NET Tasks. Metode khusus itu memiliki muatan set parameter yang berbeda yang tampaknya meningkatkan resolusi kelebihan PowerShell, jadi pada baris berikutnya kita mendapatkan yang spesifik yang hanya mengambil tugas WinRT yang dihasilkan. Kemudian kita mendefinisikan fungsi yang akan kita gunakan beberapa kali untuk mengekstrak hasil dari tipe yang sesuai dari tugas WinRT yang tidak sinkron. Setelah deklarasi fungsi itu, kami memuat dua jenis yang diperlukan dari metadata WinRT. Sisa skrip cukup banyak hanya terjemahan PowerShell dari kode C # yang Anda tulis dalam jawaban Anda; menggunakan Radiokelas WinRT untuk menemukan dan mengkonfigurasi radio Bluetooth.

Ben N
sumber
1
Anda tidak dapat memanggil metode pada ekspresi bernilai nol. Di C: \ Users \ chx \ AppData \ Local \ Microsoft \ WindowsApps \ bluetooth.ps1: 18 char: 1 + Menunggu ($ bluetooth.SetStateAsync ($ BluetoothStatus)) ([Layanan Windows.
chx
@ chx Anda yakin mesin Anda memiliki adaptor Bluetooth? Jika tidak ada radio Bluetooth, saluran ketiga ke terakhir akan diatur $bluetoothke nol, yang akan menyebabkan saluran kedua ke terakhir menghasilkan kesalahan itu.
Ben N
Saya 100% yakin itu terlihat di aplikasi "Pengaturan" dan saya mendengarkan musik secara nirkabel dan Pengelola Perangkat dan wmic juga melaporkannya.
chx
@ chx Hmm, apa yang Anda dapatkan jika Anda mengganti tiga baris terakhir hanya dengan $radios? Itu akan menampilkan daftar radio yang dikembalikan oleh WinRT.
Ben N
2
Pintar, berhasil! Saya tidak bisa mengkompilasi aplikasi desktop menggunakan API ini, tetapi memuatnya secara dinamis dalam skrip tampaknya menjadi cara yang harus dilakukan. Sekarang, bandingkan dengan rfkill unblock bluetoothdi Linux :-D
Martin Pecka
5

Setelah menyerah untuk mencari solusi yang sudah jadi, saya menemukan bahwa aplikasi Universal Windows Platform memiliki akses ke API kontrol radio .

Jadi saya menggabungkan sampel aplikasi kontrol radio dengan aplikasi yang dikontrol commandline, dan hasilnya ada di sini: https://github.com/peci1/RadioControl . Ini diterbitkan di Windows Store .

Secara umum, tidak mungkin membiarkan aplikasi berjalan di latar belakang, jadi Anda harus meluncurkan GUI terlebih dahulu, dan kemudian Anda dapat memanggilnya dari commandline seperti

radiocontrol.exe 0 on
radiocontrol.exe Bluetooth off

Fitur inti yang dibutuhkan aplikasi ini adalah:

using Windows.Devices.Radios;
await Radio.RequestAccessAsync();
var radios = await Radio.GetRadiosAsync();
await radios[0].SetStateAsync(RadioState.On);

Maka Anda juga perlu menambahkan kemampuan Radio ke manifes aplikasi:

<DeviceCapability Name="radios" />

Dan untuk memungkinkan kontrol dari commandline, Anda perlu mengganti metode protected override async void OnActivated(IActivatedEventArgs args)di App.xaml.cs dan melakukan pemrosesan dalam cabang seperti ini:

switch (args.Kind)
        {
            case ActivationKind.CommandLineLaunch:
Martin Pecka
sumber
Jawaban ini lebih cocok untuk StackOverflow.
harrymc
@ MartinPecka Secara kebetulan, apakah Anda tahu cara menghubungkan kembali perangkat Bluetooth yang telah terputus menggunakan Disable/Enable-NetAdapter? superuser.com/questions/1444278/…
JinSnow
3

Script Autohotkey ini sepertinya melakukan triknya. Saya terganggu oleh Sleepsana tetapi tampaknya jendela menjadi aktif sebelum siap menerima penekanan tombol saya.

SendMode Input
Run, ms-settings:bluetooth
WinWaitActive, Settings
Sleep 300
Send,{Tab}{Space}
WinClose, A

Crossposted ke /programming//q/48700268/308851 untuk mencari tahu apa yang Sleep 300bisa diganti dengan.

chx
sumber
Ini juga bisa menjadi solusi dalam banyak kasus. Saya juga perlu menambahkan tidur singkat setelah mengirim penekanan tombol. Dan solusi ini tidak berfungsi jika layar terkunci. Aplikasi Universal Windows yang saya posting di atas tidak berfungsi bahkan dengan layar terkunci.
Martin Pecka
2

Ini solusi parsial: wmic path Win32_PNPEntity where "caption like '%bluetooth%' AND DeviceID like 'USB\\%'" call disabletentu saja membuat sakelar Nyala / Mati Bluetooth menghilang dan Pengelola Perangkat melaporkan This device is disabled. (Code 22). Apakah itu cukup untuk mematikan radionya, saya tidak yakin.

Saya tidak dapat menemukan dokumentasi tentang argumen yang callditerima. Saya pikir harus ada semacam di rfkillsini.

chx
sumber
Maaf, tidak bekerja untuk saya seperti yang Anda gambarkan. Bagi saya, pemutaran Bluetooth berhenti, tetapi semua saklar bluetooth di panel kontrol tetap menyala. Dan menelepon dengan enabletidak melanjutkan pemutaran Bluetooth. Dokumentasi tentang kelas PNPEntity ada di sini: msdn.microsoft.com/en-us/library/aa394353(v=vs.85).aspx , tetapi tampaknya tidak ada metode lain yang bermanfaat di sana ...
Martin Pecka
1

Anda dapat menggunakan DevManView untuk mengaktifkan / menonaktifkan perangkat dari baris perintah menggunakan sintaks ini:

devmanview /disable <Device Name>   
devmanview /enable <Device Name>    

Ini juga memungkinkan penggunaan wildcard dengan /use_wildcardargumen.

rahuldottech
sumber
Devmanview memang alat yang berguna, tetapi itu tidak menyelesaikan masalah saya. Masalahnya adalah sepertinya tidak ada perangkat yang bisa Anda nonaktifkan di manajer perangkat untuk mematikan radio bluetooth.
Martin Pecka
@ MartinPecka Apakah Anda tidak melihat ini? i.stack.imgur.com/UrOuc.png Jika tidak, Anda mungkin ingin mencoba dan memperbarui driver ...
rahuldottech
Saya memang melihat perangkat Bluetooth, tetapi menonaktifkannya tidak menghentikan pemutaran - mungkin karena sistem harus di-restart agar benar-benar dinonaktifkan (seperti yang dinyatakan dalam pertanyaan awal).
Martin Pecka
0

Powershell memiliki cmdlet untuk melakukan persis apa yang Anda cari:

https://gallery.technet.microsoft.com/PowerShell-Device-60d73bb0

Gunakan Get-Device untuk mendapatkan daftar perangkat. Anda dapat menyalurkan melalui mana-objek untuk memilih perangkat Anda dan kemudian pipa itu ke Disable-Device atau Enable-Device.

Petunjuk Lengkap ...

Unduh dan unzip file tersebut.

Mulai PowerShell sebagai admin.

Ubah kebijakan eksekusi jika perlu:

Set-ExecutionPolicy Unrestricted

Impor modul:

Import-Module .\DeviceManagement.psd1

Jika Anda perlu mempersempit daftar perangkat Anda dapat menggunakan -seperti perbandingan:

Get-Device | Where-Object {$_.Name -like '*bluetooth*'}

Jika Anda tahu nama persisnya, Anda bisa menggunakan -eq (sama dengan) dibandingkan:

Get-Device | Where-Object {$_.Name -eq 'Martin's Bluetooth Adapter'} | Disable-Device -Confirm:$False

Usap tangan dengan celana.

apocalysque
sumber
Ini akan menonaktifkan perangkat USB, bukan hanya radio. wmicdapat melakukan ini juga, setidaknya saya pikir begitu.
chx
Pertanyaannya tidak menanyakan cara menonaktifkan radio tetapi tidak pada adaptor. Mengapa dibedakan? Jika Anda dapat memberi saya alasan yang bagus, saya akan mempertimbangkan untuk menggali untuk Anda, tetapi saya menjawab pertanyaan yang diajukan, "Apa yang saya benar-benar tertarik adalah cara untuk menonaktifkan / mengaktifkan adaptor Bluetooth. - Martin Pecka 5 Feb di 9:31 "
apocalysque
Maaf, apa bedanya adaptor dan radio? Saya menganggap kedua istilah ini setara. Ada banyak perangkat perangkat lunak yang disediakan oleh HW ini, dan Anda benar pertanyaan ini bukan tentang mereka.
Martin Pecka
Selain itu, skrip PS 2012 dan 2012 dari Ricardo Mendes ini tidak berfungsi di Win 10 1709 64bit saya, seperti yang disebutkan dalam komentar mereka. Keduanya berakhir dengan kesalahan Disable-Device : Error calling SetupDiCallClassInstaller. Saya menjalankannya sebagai admin dan dengan kebijakan eksekusi tidak terbatas.
Martin Pecka
0

Saya membuat skrip batch yang memeriksa nilai kunci reg yang hanya akan ada jika radio bluetooth Anda diaktifkan. Ia kemudian memanggil skrip powershell Ben N di atas dengan parameter yang benar untuk beralih ke kondisi saat ini. Mengubahnya menjadi pintasan toggle, daripada harus menggunakan dan mematikan secara terpisah.

@echo off
FOR /F "skip=2 tokens=2,*" %%A IN ('reg.exe query "HKLM\SYSTEM\CurrentControlSet\Services\bthserv\Parameters\BluetoothControlPanelTasks" /v "state"') DO set "VAR=%%B"

if %VAR%==0x1 (goto ON)

Powershell.exe -executionpolicy remotesigned -windowstyle hidden -File ".\bluetooth.ps1" -BluetoothStatus On
goto end

:ON
Powershell.exe -executionpolicy remotesigned -windowstyle hidden -File ".\bluetooth.ps1" -BluetoothStatus Off

:end
007 kerajinan
sumber
-1

Menjalankan perintah berikut dari Command Prompt (sebagai administrator) melakukan trik:

netsh interface set interface name="Bluetooth Network Connection" admin=disabled

Saya sebelumnya telah menggunakan perintah yang sama untuk menonaktifkan adaptor Wi-Fi saya, dan menemukan bahwa itu juga bekerja dengan adaptor lain di: Control Panel> Network dan Internet> Network Connections. Ubah saja argumen "nama" menjadi nama adaptor Anda. Anda juga dapat mengaktifkannya kembali dengan mengubah argumen terakhir menjadi admin=enabled.

Micah Vertal
sumber
1
Ini juga tampaknya hanya menonaktifkan driver PAN, tetapi tidak mematikan perangkat radio itu sendiri (di panel kontrol, Bluetooth masih dilaporkan sebagai "aktif").
Martin Pecka
Diverifikasi sekarang oleh uji repro bluetooth, tidak mematikan bluetooth.
Martin Pecka
Maaf @ peci1, saya salah mengerti pertanyaan Anda. Saya sebelumnya telah melihat pertanyaan yang berkaitan dengan menonaktifkan Bluetooth dan menafsirkan pertanyaan Anda sebagai hal yang sama. Jadi, tujuan Anda adalah mematikan ( mematikan daya) perangkat Bluetooth? Saya akan meneliti sedikit dan memberi tahu Anda jika saya menemukan sesuatu.
Micah Vertal
@ peci1 apakah tautan ini akan membantu?
Micah Vertal
Tidak. Ini tentang USB, bukan perangkat Bluetooth. Dan Cmdlet Manajemen Perangkat yang ditautkan juga tidak berfungsi.
Martin Pecka