C# Windows进程启动以静默方式失败-can';t在某些情况下启动蓝牙设置
尽管在Windows 10中启动(大部分?)各种控制面板屏幕,但一个特定的场景似乎失败了: 如果机器在蓝牙关闭(未禁用)的情况下启动,则运行应打开蓝牙设置屏幕的命令不会执行任何操作。该命令可以是ms设置:bluetooth,bthprops.cpl或ms设置:bluetooth 我还尝试直接启动Bluetooth Devices(蓝牙设备)屏幕(使用命令%windir%\explorer.exe shell::{28803F59-3A75-4058-995F-4EE5503B023C}as),但单击此窗口中的“蓝牙设置”也没有效果 要直接进入Bluetooth settings(蓝牙设置)屏幕,无需通过主控制面板窗口,也无需首先打开蓝牙,唯一的方法是右键单击Windows操作中心中的相关互动程序: 虽然这看起来像是操作系统级别的一个bug,但我想知道是否有任何方法可以从C#代码中知道何时启动失败。因此,我尝试使用以下代码:C# Windows进程启动以静默方式失败-can';t在某些情况下启动蓝牙设置,c#,winapi,bluetooth,windows-10,win32-process,C#,Winapi,Bluetooth,Windows 10,Win32 Process,尽管在Windows 10中启动(大部分?)各种控制面板屏幕,但一个特定的场景似乎失败了: 如果机器在蓝牙关闭(未禁用)的情况下启动,则运行应打开蓝牙设置屏幕的命令不会执行任何操作。该命令可以是ms设置:bluetooth,bthprops.cpl或ms设置:bluetooth 我还尝试直接启动Bluetooth Devices(蓝牙设备)屏幕(使用命令%windir%\explorer.exe shell::{28803F59-3A75-4058-995F-4EE5503B023C}as),但
try
{
var process = new Process();
process.StartInfo.FileName = "control";
process.StartInfo.Arguments = "bthprops.cpl";
process.Exited += (s, e) =>
{
if (process.ExitCode != 0)
{
TurnOnBt();
}
};
var res = process.Start();
if (!res)
{
TurnOnBt();
}
}
catch (System.Exception ex)
{
int test = 6; // just for breakpoint
}
问题是,从未抛出任何异常,并且在大多数情况下从未调用Process.Exit事件
此外,调用Windows.Devices.Radios.Radio.getRadioAsync()将返回一个空列表
目前我找到的唯一解决方案是手动打开蓝牙-它不会改变Process.Start/Exit行为,但它确实允许成功地使用命令直接打开Bluetooth Settings(蓝牙设置)窗口,并获取机器的蓝牙/无线电设备列表。然而,当关闭蓝牙并重新启动机器时,同样的问题会再次发生
关于基于代码的解决方案,有什么想法吗?注意-所有这些都是基于我的调试研究,没有任何文档记录
我通过行动中心(win8.1,win 10)查看BT设置窗口是如何打开的: 使用以下命令创建和调用方法的接口: appUserModelId=
L“windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel”
参数=L“page=SettingsPagePCSystemBluetooth”
<> C++代码可以是:
if (0 <= CoInitialize(0))
{
IApplicationActivationManager* pAppAct;
if (0 <= CoCreateInstance(__uuidof(ApplicationActivationManager), 0, CLSCTX_ALL, IID_PPV_ARGS(&pAppAct)))
{
ULONG dwProcessId;
pAppAct->ActivateApplication(
L"windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel",
L"page=SettingsPagePCSystemBluetooth",
AO_NONE ,
&dwProcessId);
pAppAct->Release();
}
CoUninitialize();
}
if(0 Release();
}
coninitialize();
}
对“X:\Windows\ImmersiveControlPanel\SystemSettings.exe”-ServerName:microsoft.Windows.ImmersiveControlPanel
对于c#-看
“windows.immersivecontrolpanel\u cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel”
和“page=SettingsPagePCSystemBluetooth”
字符串在任何地方都没有记录,我不确定它是否是“持久的”—但目前它用于在系统设置中打开管理Bluetooth页面
如果我们运行
control.exe bthprops.cpl
,则进程(control.exe
)启动时没有任何错误,因此您调用此代码时不会收到任何错误
然后control.exe bthprops.cpl
exec新进程rundll32.exe Shell32.dll,control\u RunDLL bthprops.cpl,
并退出
rundll32.dll
callControl\u RunDLLW(HWND\u桌面,(HINSTANCE)和图像库,L“bthprops.cpl”,SW\u SHOWDEFAULT);
我们可以直接调用void WINAPI Control\u RunDLLW(HWND hwndpresent,HINSTANCE hInst,PCWSTR cplName,int nCmdShow);
这个从shell32.dll导出的api
在内部
Control\u RunDLLW
load“bthprops.cpl”
(第三个参数-cplName),找到入口点,并发送消息。此消息检查中的bthprops.cpl
是bthserv
通过OpenService(L“bthserv”,)运行的+QueryServiceStatus
(在函数bthpisbluetoothservicesrunning
)中,如果“BTHSERV”
未运行,则返回零(失败代码)使shell显示其对话框的适当工具是。作为一个额外的优点,此API调用返回错误代码。控制bthprops.cpl
成功启动(因此您不会收到任何错误)启动rundl32.exe Shell32.dll,Control\u RunDLL bthprops.cpl,
并无错误地退出。Control\u RunDLL
loadbthprops.cpl
并调用。CPlApplet
查询服务状态bthserv
-如果它没有运行-错误返回并结束。bthprops.cpl
不想工作fbthserv
notrunning@RbMm谢谢!您能分享一下您用来获取此流的工具吗?还有,这与单击“操作中心”时发生的情况有何不同?@IInspectable我已尝试添加process.StartInfo.UseShellExecute=true;如前所述,但这不会影响任何事情。我不确定是否使用Dllimport(like)会有所不同吗?我使用调试器。不幸的是,即使您直接从自己的进程调用Control\u RunDLLW(HWND\u DESKTOP,(HINSTANCE)和\uu ImageBase,L“bthprops.cpl”,SW\u SHOWDEFAULT);
(这是会发生的事情,但在rundll32中执行Control bthprops.cpl
)-您没有收到任何错误。什么都没有。bthprops.cpl
当收到cpl_INIT
消息时,检查是否BTHSERV
正在运行(通过bthpisbluetoothservicesrunning
),如果服务未运行返回0(失败),请提供指向参考文档的链接,或将相应的常量和函数调用明确标记为“非官方”和/或“不支持”。@IInspectable-你的意思是Control\u RunDLLW
?它没有正式的文档记录。但是,在本部分中,我只解释当我们运行Control bthprops.cpl
时会发生什么-为什么这不会有明显的效果(如果bthserv
没有运行)没有返回错误。关于windows.immersivecontrolpanel\u cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel
——当然也没有文档记录