900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > python可执行程序必须以管理员_Python实现管理员权限运行CMD指令

python可执行程序必须以管理员_Python实现管理员权限运行CMD指令

时间:2024-03-08 07:24:54

相关推荐

python可执行程序必须以管理员_Python实现管理员权限运行CMD指令

一、subprocess.Popen

Python执行 cmd指令属于外部调用,subprocess.Popen 方法即可,实现如下:

# !/usr/bin/python3

# coding: utf-8

import subprocess

def command(cmd, timeout=1800000):

try:

sp = subprocess.Popen(

cmd,

shell=True,

stdout=subprocess.PIPE,

stderr=subprocess.PIPE

)

print("[PID] %s: %s" % (sp.pid, cmd))

sp.wait(timeout=timeout)

stderr = str(sp.stderr.read().decode("gbk")).strip()

stdout = str(sp.stdout.read().decode("gbk")).strip()

if "" != stderr:

raise Exception(stderr)

if stdout.find("失败") > -1:

raise Exception(stdout)

except Exception as e:

raise e

参考资料

《Python脚本以管理员权限运行》

二、bat 获取管理员权限

但当系统权限不足时,肿么办?

先看传统 bat的处理方式:

@echo off

echo get admin rights

cacls.exe "%SystemDrive%\System Volume Information" >nul 2>nul

if %errorlevel%==0 goto isAdmin

if exist "%temp%\getAdmin.vbs" del /f /q "%temp%\getAdmin.vbs"

echo Set shell = CreateObject^("Shell.Application"^)>"%temp%\getAdmin.vbs"

echo shell.ShellExecute "%~s0","","","runas",1 >>"%temp%\getAdmin.vbs"

echo WScript.Quit >>"%temp%\getAdmin.vbs"

"%temp%\getAdmin.vbs" /f

if exist "%temp%\getAdmin.vbs" del /f /q "%temp%\getAdmin.vbs"

exit

:isAdmin

sc stop WebClient

pause

这段代码的主要流程:

1、调用cacls.exe 程序查询“系统卷标信息”,验证是否具备管理员权限

2、不具备管理员权限时创建getAdmin.vbs脚本,脚本内容如下

Set shell = CreateObject("Shell.Application")

shell.ShellExecute "%~s0","","","runas",1

WScript.Quit

3、强制执行这个 getAdmin.vbs脚本

4、删除 getAdmin.vbs脚本文件 并退出

那么getAdmin.vbs脚本又做了什么呢?

脚本内容只有三行

①Set shell = CreateObject("Shell.Application")创建 Shell对象

② 以管理员权限运行当前脚本(bat脚本),其中参数 "%~s0" 是当前脚本的绝对路径,"runas"是 shell指令 runas,"1"是管理员权限

③ 脚本退出

总体流程就是 bat在权限不足情况下创建了一个 vb脚本,让 vb脚本反向调用bat

三、Python 的曲线救国

想要做一个工具类,可以实现任意 cmd指令的管理员权限下的执行

挖坑式的自造轮子:

① 创建一个空的 bat文件,动态写入cmd指令

② 创建一个固定内容的 vb脚本

③ Python调用 vb脚本, vb 调用 bat

1、文件结构

2、../tool/script/shell.vbs

cwd = CreateObject("Scripting.FileSystemObject").GetFile(Wscript.ScriptFullName).ParentFolder.Path

path = cwd & "\cmd.bat"

Set shell = CreateObject("Shell.Application")

shell.ShellExecute path,"","","runas",1

WScript.Quit

参考资料

《VBS获取当前路径的两个方法》

《VBS中字符串拼接 & 与 + 的区别》

3、方法实现

工具方法 runAdmin 实现代码如下:

注意:因 cmd指令是动态写入文件,固 runAdmin方法不支持并发,调用时要加线程锁

# !/usr/bin/python3

# coding: utf-8

import os

import subprocess

import traceback

def runAdmin(cmd, timeout=1800000):

f = None

try:

bat = os.getcwd() + r"\tool\script\cmd.bat"

f = open(bat, 'w')

f.write(cmd)

except Exception as e:

traceback.print_exc()

raise e

finally:

if f:

f.close()

try:

shell = os.getcwd() + r"\tool\script\shell.vbs"

sp = subprocess.Popen(

shell,

shell=True,

stdout=subprocess.PIPE,

stderr=subprocess.PIPE

)

print("[PID] %s: %s" % (sp.pid, cmd))

sp.wait(timeout=timeout)

stderr = str(sp.stderr.read().decode("gbk")).strip()

stdout = str(sp.stdout.read().decode("gbk")).strip()

if "" != stderr:

raise Exception(stderr)

if stdout.find("失败") > -1:

raise Exception(stdout)

except Exception as e:

raise e

如有纰漏,敬请@

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。