آموزش مدیریت Registry ویندوز با استفاده از Air و Python

شروع موضوع توسط yaa110 ‏22 اکتبر 2013 در انجمن برنامه فلش Flash

کلمات کلیدی:
  1. yaa110

    yaa110 کاربر فعال

    ارسال‌ها:
    206
    تشکر شده:
    507
    امتیاز دستاورد:
    16
    دانلود: https://github.com/yaa110/Adobe-Air-Registry-Modifier

    مدیریت Registry در ویندوز به صورت مستقیم در Air امکان پذیر نیست که دلیل این امر را به ماهیت cross-platform این SDK نسبت داده اند. اما به کمک کلاس NativeProcess و یک زبان واسطه مثل Python می توان به Registry ویندوز دسترسی داشت و آن را به صورت غیرمستقیم از داخل پروژه Adobe Air کنترل کرد. پس ابتدا باید کدهای مورد نیاز برای کنترل Registry در زبان واسطه (در این جا از Python استفاده شده است) نوشته شود. علت استفاده از زبان Python در این مثال، امکان ایجاد یک خروجی exe به صورت standalone است که بدون نیاز به نصب Python در سیستم کاربر قابل استفاده می باشد.

    برای کدنویسی از Python 2.7 استفاده شد و خروجی نهایی توسط py2exe آماده شد. درصورتی که با زبان Python آشنایی ندارید، می توانید از خروجی نهایی که در فایل Sample قرار دارد استفاده کنید (محتویات این خروجی در فولدر dist قرار دارد). کدهای نوشته شده برای کنترل Registry در Python به صورت زیر می باشد:

    کد (Text):
    [COLOR=#222222][FONT=Tahoma]import _winreg[/FONT][/COLOR]import sys


    # switch (rootkey)
    root_keys = {
                 "HKEY_LOCAL_MACHINE" : _winreg.HKEY_LOCAL_MACHINE,
                 "HKEY_CLASSES_ROOT" : _winreg.HKEY_CLASSES_ROOT,
                 "HKEY_CURRENT_CONFIG" : _winreg.HKEY_CURRENT_CONFIG,
                 "HKEY_CURRENT_USER" : _winreg.HKEY_CURRENT_USER,
                 "HKEY_USERS" : _winreg.HKEY_USERS
                 }


    # Get arguments
    for i in sys.argv:
        try:
            if i.find("-key") != -1: k = i.split(":")[1]
            elif i.find("-value") != -1: v = i.split(":")[1]
            elif i.find("-path") != -1: p = i.split(":")[1]
            elif i.find("-rootkey") != -1: rk = i.split(":")[1]
            elif i.find("-action") != -1: a = i.split(":")[1]
        except Exception as e:
            sys.stderr.write("Invalid argument: " + str(e))


    # Functions
    def read_key():
        try:
            hKey = _winreg.OpenKey(root_keys[rk.upper()], p)
            _value, _type = _winreg.QueryValueEx (hKey, k)
            sys.stdout.write(_value)
        except Exception as e:
            sys.stderr.write("Error: " + str(e))


    def write_key():
        try:
            key = _winreg.CreateKey(root_keys[rk.upper()], p)
            _winreg.SetValueEx(key, k, 0, _winreg.REG_SZ, v)
            sys.stdout.write('Key has been created.')
        except Exception as e:
            sys.stderr.write("Error: " + str(e))


    def delete_key():
        try:
            _winreg.DeleteKey(root_keys[rk.upper()], p)
            sys.stdout.write('Key has been deleted.')
        except Exception as e:
            sys.stderr.write("Error: " + str(e))


    # switch (action)
    actions = {
               "read" : read_key,
               "write" : write_key,
               "delete" : delete_key          
               }


    try:
        actions[a.lower()]()
    except Exception as e:
    [COLOR=#222222][FONT=Tahoma]    sys.stderr.write("Invalid action: " + str(e))[/FONT][/COLOR]
    در این کدها ابتدا argument های ارسال شده توسط Command line دریافت می شود و سپس از ماژول winreg برای ایجاد، حذف و خواندن اطلاعات Registry استفاده شده است. همچنین با استفاده از stderr و stdout اطلاعات مورد نیاز به Air ارسال می شود. در ادامه کلاسی را که برای دریافت اطلاعات از برنامه Python نوشته شده است، مشاهده می کنید (این کلاس نیز در فایل Sample وجود دارد):

    کد (Text):
    [COLOR=#222222][FONT=Tahoma]package ir.flashcenter {[/FONT][/COLOR]    import flash.events.EventDispatcher;
        import flash.desktop.NativeProcess;
        import flash.desktop.NativeProcessStartupInfo;
        import flash.events.ProgressEvent;
        import flash.events.NativeProcessExitEvent;
        import flash.filesystem.File;
        import flash.events.Event;
       
        public class RegistryModify extends EventDispatcher {
           
            var _np:NativeProcess;
            var _npi:NativeProcessStartupInfo;
            var _args:Vector.<String>;
            var exePath:String;
           
            public var _output:String;
           
            public function RegistryModify(_exePath:String) {
                exePath = _exePath;
            }
           
            public function readValue(_rootKey:String, _path:String, _key:String):void {
                _args = new Vector.<String>();
                _args.push("-action:read", "-key:" + _key, "-path:" + _path, "-rootkey:" + _rootKey);
                process();
            }
           
            public function writeValue(_rootKey:String, _path:String, _key:String, _value:String):void {
                _args = new Vector.<String>();
                _args.push("-action:write", "-key:" + _key, "-value:" + _value, "-path:" + _path, "-rootkey:" + _rootKey);
                process();
            }
           
            public function deleteKey(_rootKey:String, _path:String):void {
                _args = new Vector.<String>();
                _args.push("-action:delete", "-path:" + _path, "-rootkey:" + _rootKey);
                process();
            }
           
            private function process():void {
                _npi = new NativeProcessStartupInfo();
                _npi.executable = File.applicationDirectory.resolvePath(exePath);
                _npi.arguments = _args;
               
                _np = new NativeProcess();
                _np.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
                _np.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorData);
                _np.addEventListener(NativeProcessExitEvent.EXIT, onExit);
                _np.start(_npi);
            }
           
            private function onOutputData(e:ProgressEvent):void {
                _output = String(_np.standardOutput.readUTFBytes(_np.standardOutput.bytesAvailable));
                dispatchEvent(new Event("OutputData"));
            }
           
            private function onErrorData(e:ProgressEvent):void {
                _output = String(_np.standardError.readUTFBytes(_np.standardError.bytesAvailable));
                dispatchEvent(new Event("ErrorData"));
            }
           
            private function onExit(e:NativeProcessExitEvent):void {
                dispatchEvent(new Event(Event.COMPLETE));
            }


        }
       
    [COLOR=#222222][FONT=Tahoma]}[/FONT][/COLOR]
    در این کلاس:

    <Vector.<String: از این وکتور برای دریافت Argument های ورودی مورد نیاز جهت اجرای فایل exe (ایجاد شده با Python) به صورت command line استفاده شده است. به طور کلی این وکتور را می توان مشابه یک آرایه درنظر گرفت که درایه های آن String هستند و با دستور push اضافه شده اند.

    NativeProcessStartupInfo: از این کلاس برای معرفی اطلاعات مورد نیاز برای اجرای فایل Exe ایجاد شده با Python استفاده شده است. این اطلاعات شامل Argument های ورودی و آدرس فایل exe نسبت به فایل پروژه Air می باشد.

    NativeProcess: این کلاس وظیفه ارسال اطلاعات به فایل exe و سپس دریافت آن را برعهده دارد.

    STANDARD_OUTPUT_DATA: به وسیله این رویداد می توان اطلاعات ارسال شده توسط دستور stdout در Python را دریافت کرد.

    STANDARD_ERROR_DATA: این رویداد نیز می تواند اطلاعات ارسال شده از دستور stderr را نمایش دهد.

    NativeProcessExitEvent: با استفاده از این کلاس و رویداد EXIT زمان پایان پروسه فایل exe مشخص می شود که معادل با زمانی است که فایل exe بسته می شود.

    برای استفاده از این کلاس، می توانید یک پروژه Air ایجاد کنید و سپس کدهای زیر را در فریم مورد نظر بنویسید:

    کد (Text):
    [COLOR=#222222][FONT=Tahoma]import ir.flashcenter.RegistryModify;[/FONT][/COLOR]import flash.events.Event;


    var modify:RegistryModify = new RegistryModify("dist/registry.exe");
    modify.addEventListener(Event.COMPLETE, onComplete);
    modify.addEventListener("OutputData", onOutputData);
    modify.addEventListener("ErrorData", onErrorData);


    function onOutputData(e:Event):void {
        trace("Value: " + modify._output);
    }


    function onErrorData(e:Event):void {
        trace("Error: " + modify._output);
    }


    function onComplete(e:Event):void {
        trace("End of Process");
    [COLOR=#222222][FONT=Tahoma]}[/FONT][/COLOR]
    در این مثال ابتدا یک شی از کلاس RegistryModify ایجاد شده است. سپس برای دریافت اطلاعات ارسالی از کلاس در زمان دریافت اطلاعات، دریافت خطا و پایان پروسه یک Listener تعریف شده است.

    برای ایجاد اطلاعات در Registry می توانید از کد مشابه زیر استفاده کنید (دقت کنید که مقادیر ورودی تابع را با توجه به نیاز خود می توانید تغییر دهید):

    کد (Text):
    [COLOR=#222222][FONT=Tahoma]/* Write data */[/FONT][/COLOR][COLOR=#222222][FONT=Tahoma]modify.writeValue("HKEY_CURRENT_USER", "test\\flashcenter\\", "source", "flashcenter.ir");[/FONT][/COLOR]
    به منظور خواندن اطلاعات Registry از کد مشابه زیر استفاده کنید:

    کد (Text):
    [COLOR=#222222][FONT=Tahoma]/* Read data */[/FONT][/COLOR][COLOR=#222222][FONT=Tahoma]modify.readValue("HKEY_CURRENT_USER", "test\\flashcenter\\", "source");[/FONT][/COLOR]
    درنهایت برای حذف اطلاعات از Registry می توانید از کد مشابه زیر استفاده کنید:

    کد (Text):
    [COLOR=#222222][FONT=Tahoma]/* Delete data */[/FONT][/COLOR][COLOR=#222222][FONT=Tahoma]modify.deleteKey("HKEY_CURRENT_USER", "test\\flashcenter\\");[/FONT][/COLOR]
    در پایان یادآوری می کنم که می توانید از زبان های واسطه دیگر هم برای مدیریت Registry استفاده کنید، اما در زمان ایجاد خروجی exe دقت کنید که این خروجی حتما 32 بیتی باشد و بتواند به صورت standalone اجرا شود (یعنی نیازی به نصب Library های آن توسط کاربر نباشد). همچنین برای فعال کردن کلاس NativeProcess حتما باید پروفایل پروژه را روی Extended Desktop تنظیم کنید (سایر پروفایل ها باید غیرفعال باشند). تنظیمات این قسمت در نرم افزار Flash Pro در منوی File و Air Settings قرار دارد.

    دانلود: https://github.com/yaa110/Adobe-Air-Registry-Modifier
     
    آخرین ویرایش: ‏20 نوامبر 2014
    نوشته شده توسط yaa110 در ‏22 اکتبر 2013
    Dorhato، wgolzar، Mehrdad155 و 3 نفر دیگر از این ارسال تشکر کرده اند.

به اشتراک بگذارید