هل تريد طلب UAC من خلال نص برمجي Python؟




windows windows-vista (7)

أريد برنامج نصي Python نسخ الملفات على Vista. عندما أقوم بتشغيلها من نافذة cmd.exe عادية ، لا يتم إنشاء أي أخطاء ، ولكن لا يتم نسخ الملفات. إذا قمت بتشغيل cmd.exe "كمسؤول" ثم قم بتشغيل البرنامج النصي الخاص بي ، فإنه يعمل بشكل جيد.

هذا أمر منطقي لأن التحكم في حساب المستخدم (UAC) يمنع عادةً العديد من إجراءات نظام الملفات.

هل هناك طريقة يمكنني بها ، من داخل نص بيثون ، استدعاء طلب رفع UAC (تلك الحوارات التي تقول شيئًا مثل "مثل هذا التطبيق يحتاج إلى وصول المشرف ، هل هذا موافق؟")

إذا لم يكن ذلك ممكنًا ، فهل هناك طريقة يمكن للبرنامج النصي أن يكتشفها على الأقل أنها ليست مرتفعة حتى يمكن أن تفشل برشاقة؟


إذا كان البرنامج النصي الخاص بك يتطلب دائمًا امتيازات المسؤول ، فيمكنك:

runas /user:Administrator "python your_script.py"

استغرق الأمر بعض الوقت للحصول على إجابة dguaraglia ، لذلك من أجل توفير وقت الآخرين ، إليك ما فعلته لتنفيذ هذه الفكرة:

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)

قد لا يجيب هذا على سؤالك تمامًا ولكن يمكنك أيضًا تجربة استخدام Elevate Command Powertoy لتشغيل البرنامج النصي بامتيازات UAC المرتفعة.

http://technet.microsoft.com/en-us/magazine/2008.06.elevation.aspx

أعتقد أنه إذا كنت تستخدمها ، فستبدو وكأنها "ترفيث python yourscript.py"


لقد تم طرح هذا السؤال قبل عدة سنوات ، وأعتقد أن هناك حل أكثر أناقة يتم تقديمه على github بواسطة frmdstryr باستخدام باسمينوتيلس الوحدة النمطية له:

مقتطفات:

import pythoncom
from win32com.shell import shell,shellcon

def copy(src,dst,flags=shellcon.FOF_NOCONFIRMATION):
    """ Copy files using the built in Windows File copy dialog

    Requires absolute paths. Does NOT create root destination folder if it doesn't exist.
    Overwrites and is recursive by default 
    @see http://msdn.microsoft.com/en-us/library/bb775799(v=vs.85).aspx for flags available
    """
    # @see IFileOperation
    pfo = pythoncom.CoCreateInstance(shell.CLSID_FileOperation,None,pythoncom.CLSCTX_ALL,shell.IID_IFileOperation)

    # Respond with Yes to All for any dialog
    # @see http://msdn.microsoft.com/en-us/library/bb775799(v=vs.85).aspx
    pfo.SetOperationFlags(flags)

    # Set the destionation folder
    dst = shell.SHCreateItemFromParsingName(dst,None,shell.IID_IShellItem)

    if type(src) not in (tuple,list):
        src = (src,)

    for f in src:
        item = shell.SHCreateItemFromParsingName(f,None,shell.IID_IShellItem)
        pfo.CopyItem(item,dst) # Schedule an operation to be performed

    # @see http://msdn.microsoft.com/en-us/library/bb775780(v=vs.85).aspx
    success = pfo.PerformOperations()

    # @see sdn.microsoft.com/en-us/library/bb775769(v=vs.85).aspx
    aborted = pfo.GetAnyOperationsAborted()
    return success is None and not aborted    

يستخدم هذا واجهة COM ويشير تلقائيًا إلى أن امتيازات المسؤول مطلوبة مع مطالبة الحوار المألوفة التي قد تراها إذا كنت تقوم بالنسخ في دليل حيث تكون امتيازات المسؤول مطلوبة وكذلك توفر مربع حوار تقدم الملف النموذجي أثناء عملية النسخ.


يبدو أنه لا توجد طريقة لرفع امتيازات التطبيق لفترة من الوقت حتى تتمكن من أداء مهمة معينة. يحتاج Windows إلى معرفة في بداية البرنامج ما إذا كان التطبيق يتطلب امتيازات معينة ، وسيطلب من المستخدم تأكيد ما إذا كان التطبيق يقوم بأية مهام تتطلب تلك الامتيازات. هناك طريقتان للقيام بذلك:

  1. اكتب ملف بيان يخبر Windows بأن التطبيق قد يتطلب بعض الامتيازات
  2. قم بتشغيل التطبيق مع امتيازات مرتفعة من داخل برنامج آخر

تشرح two articles بتفصيل أكثر كيف يعمل هذا.

ما يمكنني القيام به ، إذا كنت لا ترغب في كتابة ctypes ctypes API API CreateElevatedProcess ، هو استخدام الأداة ShellExecuteEx الموضحة في مقالة Code Code (Pywin32 تأتي مع برنامج إغلاق ShellExecute). ماذا؟ شيء من هذا القبيل:

عندما يبدأ البرنامج ، فإنه يتحقق إذا كان لديه امتيازات المسؤول ، إذا لم يتم تشغيل نفسه باستخدام خدعة ShellExecute ويخرج على الفور ، إذا كان كذلك ، فإنه ينفذ المهمة في متناول اليد.

عندما تصف برنامجك بأنه "نص" ، أفترض أن هذا يكفي لاحتياجاتك.

في صحتك.


يبني المثال التالي على عمل MARTIN DE LA FUENTE SAAVEDRA الممتاز والجواب المقبول. على وجه الخصوص ، يتم إدخال اثنين من التعدادات. يسمح الأول بتحديد سهل لكيفية فتح برنامج مرتفع ، بينما يساعد الثاني على تحديد الأخطاء بسهولة. يرجى ملاحظة أنه إذا كنت تريد أن يتم تمرير جميع وسائط سطر الأوامر إلى العملية الجديدة ، sys.argv[0] المحتمل أن يتم استبدال sys.argv[0] باستدعاء دالة: subprocess.list2cmdline(sys.argv) .

#! /usr/bin/env python3
import ctypes
import enum
import sys


# Reference:
# msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx


class SW(enum.IntEnum):

    HIDE = 0
    MAXIMIZE = 3
    MINIMIZE = 6
    RESTORE = 9
    SHOW = 5
    SHOWDEFAULT = 10
    SHOWMAXIMIZED = 3
    SHOWMINIMIZED = 2
    SHOWMINNOACTIVE = 7
    SHOWNA = 8
    SHOWNOACTIVATE = 4
    SHOWNORMAL = 1


class ERROR(enum.IntEnum):

    ZERO = 0
    FILE_NOT_FOUND = 2
    PATH_NOT_FOUND = 3
    BAD_FORMAT = 11
    ACCESS_DENIED = 5
    ASSOC_INCOMPLETE = 27
    DDE_BUSY = 30
    DDE_FAIL = 29
    DDE_TIMEOUT = 28
    DLL_NOT_FOUND = 32
    NO_ASSOC = 31
    OOM = 8
    SHARE = 26


def bootstrap():
    if ctypes.windll.shell32.IsUserAnAdmin():
        main()
    else:
        hinstance = ctypes.windll.shell32.ShellExecuteW(
            None, 'runas', sys.executable, sys.argv[0], None, SW.SHOWNORMAL
        )
        if hinstance <= 32:
            raise RuntimeError(ERROR(hinstance))


def main():
    # Your Code Here
    print(input('Echo: '))


if __name__ == '__main__':
    bootstrap()

يمكنك إنشاء اختصار في مكان ما واستخدام الهدف: python yourscript.py ثم تحت خصائص وانتقائي حدد تشغيل كمسؤول.

عندما ينفذ المستخدم الاختصار ، سيطلب منه رفع التطبيق.







uac