VC开发之MoveFile失败,error code 5

    产品肯定需要迭代,前几天在迭代时就遇到了一个问题:部分用户的老版本无法更新到新版本。我用的MoveFile将老版本改名,然后下载新版本重新应用。

    MoveFile失败,GetLastError返回的错误码为5---》权限问题或者操作的对象被占用。几轮排查之后发现是权限的问题,有些用户的安装路径在C:\Program Files\下,有的在其他盘,所以其他盘的可以更新,C:\Program Files\下的无法更新。因为在Windows系统里C盘是系统盘,普通用户只有读的权限没有修改和写入的权限,所以操作其文件或是文件夹需要管理员权限的,故MoveFile改名失败导致更新失败。(不只是该函数,只要是对系统盘的操作都要注意权限问题!!!)

    解决方法:

        1.手动为普通用户添加权限(测试或者自己用,那这个方法没问题,给用户当然是不行的)

        2. 使用GetNamedSecurityInfo、SetEntriesInAcl和SetNamedSecurityInfo三个函数来修改对象的ACL,但前提是你得有管理员权限。(我获取管理员权限一直失败不知道为什么)具体可以参考以下链接:在 C++ 中修改对象的 ACL - Win32 apps | Microsoft Learn

或者博主涟幽516的文章修改 Windows 文件访问权限的多种方法_如何更改文件高级权限-CSDN博客

        3.通过icacls命令来修改文件ACL,也需要管理员权限。以下的方法本质上是差不多的,都会弹出来一个UAC窗口,需要用户确认才能获取管理员权限。(目前我是通过②解决问题的)

                ①创建一个bat脚本执行修改(脚本也可以在程序中调用)

@echo off
rem 通过批处理来更改系统文件夹的文件名
rem icacls将文件权限设置为用户完全控制,rename改名

Net session >nul 2>&1 || mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0","","runas",1)(window.close)&&exit
icacls "C:\Program Files\xxx" /grant users:F /T /Q

                ②使用ShellExecuteEx函数调用cmd执行修改

SHELLEXECUTEINFO sei = { sizeof(sei) };
    sei.lpVerb = "runas"; // 请求管理员权限
    sei.lpFile = "cmd.exe"; // 要运行的程序
    sei.lpParameters = "/c icacls \"C:\\Program Files\\xxx" /grant users:F /T /Q"; // 要执行的命令
    sei.hwnd = NULL; // 父窗口句柄
    sei.nShow = SW_NORMAL; // 显示方式

    if (!ShellExecuteEx(&sei)) {
        DWORD dwError = GetLastError();
        if (dwError == ERROR_CANCELLED) {
            // 用户拒绝了UAC对话框
        } else {
            // 其他错误
        }
    }

当然提权不止这些方法,这些都是比较简单常见的。还可以通过COM接口来提权,甚至绕过UAC弹窗无需用户确认提权。  

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值