前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【tauri开发】windows管理员身份开机启动

【tauri开发】windows管理员身份开机启动

作者头像
微芒不朽
发布2024-06-25 15:17:08
1140
发布2024-06-25 15:17:08
举报

前言

最近遇到个bug,问题一路捋上来,查到了windows权限相关,即我需要将应用改成默认使用管理员身份运行

我看了看代码,试了一下,果然tauri自带的开机启动插件[1]没能在开机时打开默认管理员权限运行的软件

经过一番搜索,找到了windows下有个名为Task Scheduler[2](任务计划程序)的东西,可以在用户登录时执行一个动作

既然可行,那说做就做

默认管理员身份

先把应用改成默认管理员身份,查了一下tauri相关issue[3],在build.rs按以下修改即可

代码语言:javascript
复制
代码语言:javascript
复制
let mut windows = tauri_build::WindowsAttributes::new();
windows = windows.app_manifest(r#"
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        processorArchitecture="*"
        publicKeyToken="6595b64144ccf1df"
        language="*"
      />
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
        <requestedPrivileges>
            <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
        </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>
"#);
tauri_build::try_build(
  tauri_build::Attributes::new().windows_attributes(windows)
).expect("failed to run build script");

到rust仓库找了一圈,找到了 windows task scheduler API的封装planif[4],看了看案例,由于对 task scheduler完全不了解,花了一段时间摸索

关于使用planif实现开机自启动,具体见此处[5]

把引用和一些无关内容去除,大致见下面

懂rust的人会觉得代码有点奇怪,但下面我就要讲踩到的坑

代码语言:javascript
复制
fn spawn_autostart(enabled: bool) -> Result<()> {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let _ = tx.send(autostart(enabled).map_err(|e| anyhow!(e.to_string())));
    });

    Ok(rx.recv().map_err(|e| anyhow!(e))??)
}

fn autostart(enabled: bool) -> std::result::Result<(), Box<dyn std::error::Error>> {
    let ts = TaskScheduler::new()?;
    let com = ts.get_com();
    let sb = ScheduleBuilder::new(&com).unwrap();

    let exe = current_exe()?;
    let exe = exe.to_str().unwrap();

    let settings = PrincipalSettings {
        display_name: "".to_string(),
        group_id: None,
        id: "".to_string(),
        logon_type: LogonType::InteractiveToken,
        run_level: RunLevel::Highest,
        user_id: Some(whoami::username()),
    };

    sb.create_logon()
        .author("hanaTsuk1")?
        .trigger("trigger", enabled)?
        .action(Action::new("auto start", exe, "", ""))?
        .in_folder("shion")?
        .principal(settings)?
        .delay(Duration {
            seconds: Some(6),
            ..Default::default()
        })?
        .build()?
        .register("auto start", TaskCreationFlags::CreateOrUpdate as i32)?;
    Ok(())
}

pub fn enable() -> Result<()> {
    spawn_autostart(true)
}

pub fn disable() -> Result<()> {
    spawn_autostart(false)
}

创建任务

在创建任务时,单独测试非常正常。但一放到tauri里运行,就会报错

无法在设置线程模式后对其加以更改。 (0x80010106)

经过一番搜索,找到错误与CoInitializeEx[6]有关,它的线程模式存在COINIT_APARTMENTTHREADEDCOINIT_MULTITHREADED两种,我使用的库planif和tauri都调用了CoInitializeEx,但选择的模式不同,于是报错

tauri官方给出的解决方案是issue[7],即开一个新线程调用CoInitializeEx

托盘消失

在成功创建完任务后,我尝试了重启看看效果,但非常奇怪并没有生效,于是我尝试了几次发现

程序的确运行了,但托盘有时存在,有时又不存在

我以为是tauri的问题,于是查了半天无果,但仔细一想平时托盘都不会出现这样的问题。会不会是开机启动时系统还没准备好,程序就运行了,于是我打开任务计划程序

发现我的程序上次运行时间总是比其他的软件要早

mmc_HSMrpjIz4O.png

于是找了找延迟相关的代码

延迟失效

我设置了延迟,但发现还是一样没有变化,折腾一圈,发现和planif[8]仓库最近的提交有关系

即作者改了bug,但crate最新版还没有改,于是把源指向github仓库

大功告成

总结

从一个坑爬出来又掉到另一个,但好歹实现了 说一下planif相关的代码

代码语言:javascript
复制
代码语言:javascript
复制
run_level: RunLevel::Highest  // 设置管理员权限

sb.create_logon()  // 创建一个用户登录后执行的动作

.trigger("trigger", enabled)?  // 通过控制enabled值来实现启用或禁用

.action(Action::new("auto start", exe, "", ""))?  // action就是要运行的软件

.in_folder("shion")?  // 看到上面那张图了吗?它会在左侧创建一个文件夹

// 名称,然后创建并更新
.register("auto start", TaskCreationFlags::CreateOrUpdate as i32)?;

更新

运行生效,正当我准备打包测试时,问题接踵而至

tauri nsis更新会下载setup程序,我在本地运行测试,发现setup程序更新完自行启动后软件却没有启动

setup是普通用户身份,包含的软件是管理员身份,是这个原因吗?

查了一下tauri的配置[9],将installMode设置为both,即可让setup程序默认以管理员身份运行

试了一下,成功


上传代码,一键github action启动,接下来便是等待release生成,然后测试真实打包情况了

不出意外的话,接下来就要出意外了🥲

点击更新、下载、运行,然后报错

一阵风慢慢吹过,只剩下电脑面前麻木的我


在后续的尝试中发现,当前是普通身份运行的程序,在更新时运行带管理员身份的setup程序,虽然会弹框确认,但这里就是会出现问题。如果原本就是管理员身份运行,就没有问题

这一次,我选择妥协😐

真正的总结

忙活了几天,总算是尘埃落地,从切换成默认管理员身份开始,牵扯出这么多问题

最后算是画上了句号

参考资料

[1]

https://github.com/tauri-apps/plugins-workspace/tree/v2/plugins/autostart: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Ftauri-apps%2Fplugins-workspace%2Ftree%2Fv2%2Fplugins%2Fautostart

[2]

https://learn.microsoft.com/zh-cn/windows/win32/taskschd/task-scheduler-start-page: https://link.juejin.cn?target=https%3A%2F%2Flearn.microsoft.com%2Fzh-cn%2Fwindows%2Fwin32%2Ftaskschd%2Ftask-scheduler-start-page

[3]

https://github.com/tauri-apps/tauri/issues/7173: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Ftauri-apps%2Ftauri%2Fissues%2F7173

[4]

https://github.com/mattrobineau/planif: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fmattrobineau%2Fplanif

[5]

https://github.com/shion-app/shion/blob/master/src-tauri/src/autostart.rs: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fshion-app%2Fshion%2Fblob%2Fmaster%2Fsrc-tauri%2Fsrc%2Fautostart.rs

[6]

https://learn.microsoft.com/zh-cn/windows/win32/api/combaseapi/nf-combaseapi-coinitializeex: https://link.juejin.cn?target=https%3A%2F%2Flearn.microsoft.com%2Fzh-cn%2Fwindows%2Fwin32%2Fapi%2Fcombaseapi%2Fnf-combaseapi-coinitializeex

[7]

https://github.com/tauri-apps/tauri/issues/6485: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Ftauri-apps%2Ftauri%2Fissues%2F6485

[8]

https://github.com/mattrobineau/planif: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fmattrobineau%2Fplanif

[9]

https://tauri.app/zh-cn/v1/api/config/#nsisinstallermode: https://link.juejin.cn?target=https%3A%2F%2Ftauri.app%2Fzh-cn%2Fv1%2Fapi%2Fconfig%2F%23nsisinstallermode

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 叫我詹躲躲 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 默认管理员身份
    • 创建任务
      • 托盘消失
        • 延迟失效
          • 总结
          • 更新
          • 真正的总结
          相关产品与服务
          腾讯云服务器利旧
          云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档