72

管理タスクを実行する必要がある pyqt アプリケーションを作成しています。昇格特権でスクリプトを開始したいと思います。この質問は、SO または他のフォーラムで何度も聞かれることを承知しています。しかし、人々が提案している解決策は、この SO の質問を確認すること です Python スクリプト内から UAC 昇格を要求しますか?

ただし、リンクにあるサンプル コードを実行できません。このコードをメインファイルの上に置き、実行しようとしました。

import os
import sys
import win32com.shell.shell as shell
ASADMIN = 'asadmin'

if sys.argv[-1] != ASADMIN:
    script = os.path.abspath(sys.argv[0])
    params = ' '.join([script] + sys.argv[1:] + [ASADMIN])
    shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params)
    sys.exit(0)
print "I am root now."

実際には昇格の許可を求めますが、印刷行は実行されません。誰かが上記のコードを正常に実行するのを手伝ってくれます。前もって感謝します。

4

12 に答える 12

12

誰かからコードを受け取った回答へのコメントで、ShellExecuteEx はその STDOUT を元のシェルに戻さないと言います。そのため、コードはおそらく正常に動作しているにもかかわらず、「I am root now」は表示されません。

何かを印刷する代わりに、ファイルに書き込んでみてください:

import os
import sys
import win32com.shell.shell as shell
ASADMIN = 'asadmin'

if sys.argv[-1] != ASADMIN:
    script = os.path.abspath(sys.argv[0])
    params = ' '.join([script] + sys.argv[1:] + [ASADMIN])
    shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params)
    sys.exit(0)
with open("somefilename.txt", "w") as out:
    print >> out, "i am root"

次に、ファイルを調べます。

于 2013-10-30T21:36:52.210 に答える
5

stdout リダイレクトを使用したソリューションを次に示します。

def elevate():
    import ctypes, win32com.shell.shell, win32event, win32process
    outpath = r'%s\%s.out' % (os.environ["TEMP"], os.path.basename(__file__))
    if ctypes.windll.shell32.IsUserAnAdmin():
        if os.path.isfile(outpath):
            sys.stderr = sys.stdout = open(outpath, 'w', 0)
        return
    with open(outpath, 'w+', 0) as outfile:
        hProc = win32com.shell.shell.ShellExecuteEx(lpFile=sys.executable, \
            lpVerb='runas', lpParameters=' '.join(sys.argv), fMask=64, nShow=0)['hProcess']
        while True:
            hr = win32event.WaitForSingleObject(hProc, 40)
            while True:
                line = outfile.readline()
                if not line: break
                sys.stdout.write(line)
            if hr != 0x102: break
    os.remove(outpath)
    sys.stderr = ''
    sys.exit(win32process.GetExitCodeProcess(hProc))

if __name__ == '__main__':
    elevate()
    main()
于 2015-07-20T06:11:37.963 に答える
5

これは、ctypes モジュールのみを必要とするソリューションです。pyinstaller でラップされたプログラムをサポートします。

#!python
# coding: utf-8
import sys
import ctypes

def run_as_admin(argv=None, debug=False):
    shell32 = ctypes.windll.shell32
    if argv is None and shell32.IsUserAnAdmin():
        return True

    if argv is None:
        argv = sys.argv
    if hasattr(sys, '_MEIPASS'):
        # Support pyinstaller wrapped program.
        arguments = map(unicode, argv[1:])
    else:
        arguments = map(unicode, argv)
    argument_line = u' '.join(arguments)
    executable = unicode(sys.executable)
    if debug:
        print 'Command line: ', executable, argument_line
    ret = shell32.ShellExecuteW(None, u"runas", executable, argument_line, None, 1)
    if int(ret) <= 32:
        return False
    return None


if __name__ == '__main__':
    ret = run_as_admin()
    if ret is True:
        print 'I have admin privilege.'
        raw_input('Press ENTER to exit.')
    elif ret is None:
        print 'I am elevating to admin privilege.'
        raw_input('Press ENTER to exit.')
    else:
        print 'Error(ret=%d): cannot elevate privilege.' % (ret, )
于 2015-11-22T14:58:34.340 に答える
0

delphifirst による解決策が機能し、昇格された特権で Python スクリプトを実行する問題に対する最も簡単で単純な解決策であることを確認できます。

Python 実行可能ファイル (python.exe) へのショートカットを作成し、python.exe への呼び出しの後にスクリプトの名前を追加してショートカットを変更しました。次にショートカットの「互換性タブ」で「管理者として実行」にチェックを入れました。ショートカットが実行されると、スクリプトを管理者として実行する許可を求めるプロンプトが表示されます。

私の特定の python アプリケーションは、インストーラー プログラムでした。このプログラムを使用すると、別の python アプリをインストールおよびアンインストールできます。私の場合、「appname install」という名前と「appname uninstall」という名前の 2 つのショートカットを作成しました。2 つのショートカットの唯一の違いは、Python スクリプト名に続く引数です。インストーラー版では、引数は「install」です。アンインストール バージョンでは、引数は「uninstall」です。インストーラー スクリプトのコードは、指定された引数を評価し、必要に応じて適切な関数 (インストールまたはアンインストール) を呼び出します。

私の説明が、昇格された特権で Python スクリプトを実行する方法を他の人がより迅速に理解するのに役立つことを願っています。

于 2016-12-06T17:32:33.463 に答える
0

アプリケーションをPyInstallerでパッケージ化するつもりで、その機能を自分でサポートするのを避けるのが賢明な場合は、開始時に UAC 昇格を要求するために--uac-adminor引数を渡すことができることに注意してください。--uac-uiaccess

于 2020-06-10T21:21:26.213 に答える