Página 1 de 1

[RESUELTO] Paquete Arduino-IDE v2.0.2

Publicado: 4 de octubre de 2022 - 11:38 a. m.
por olaplanche
Buen día,

- 24/11/2022: Código actualizado para la versión 2.0.2 con función de desinstalación para una desinstalación limpia y modificación del archivo de configuración de sesión para el idioma francés por defecto.

Estoy compartiendo mi paquete Arduino-IDE v2.0.0, que requirió bastante adaptación en comparación con la versión 1.8.19...

Primero, es importante saber que la nueva versión crea una carpeta de datos en %localappdata% para cada usuario. Es absolutamente esencial que el usuario tenga acceso completo a lectura, escritura y.. ejecución en este archivo para el correcto funcionamiento del software.
Mi problema: Utilizo una estrategia de restricción de software (SRP) que prohíbe la ejecución de ciertos tipos de archivos desde el perfil de usuario.
También es importante saber que cada vez que un usuario abre el software por primera vez, se crea una carpeta Arduino15 en %localappdata% y se descargan las bibliotecas. Esta carpeta ocupa 346 MB; si muchos usuarios usan el software, puede convertirse rápidamente en un desastre.
Y una última cosa: los controladores de Arduino ya no están incluidos en esta versión; se descargan por separado. Por lo tanto, he creado un paquete de dependencias: viewtopic.php?t=3222

Por lo tanto, propongo un código que copia la carpeta Arduino15 (recuperada anteriormente del paquete) en la carpeta c:\ProgramData\Arduino15, modifica los permisos en esta carpeta para cumplir con los requisitos previos y también modifica el archivo de configuración del software a través de la función de configuración de sesión para apuntar a la carpeta única Arduino15 para todos los usuarios.

Por lo tanto, los usuarios tendrán derechos de escritura, lectura y ejecución en esta carpeta, que está oculta en la carpeta ProgramData y es inaccesible para los usuarios a través del Explorador de Windows y está autorizada para ejecutarse en mi SRP.
También he añadido una función de auditoría para detectar si la versión anterior (<=1.8.19) está instalada porque esta versión se instala por separado.


Configuración.py:

Código: Seleccionar todo

# -*- coding: utf-8 -*-
from setuphelpers import *
import platform

"""
Usable WAPT package functions: install(), uninstall(), session_setup(), audit(), update_package()

"""
# Declaring global variables - Warnings: 1) WAPT context is only available in package functions; 2) Global variables are not persistent between calls
bin_name_string = 'arduino-ide_%s_Windows_64bit.msi'
app_uninstallkey = "{547C91EB-BA23-4620-83BA-3E850277CD61}"


def install():
    # Declaring local variables
    package_version = control.get_software_version()
    bin_name = bin_name_string % package_version
    impacted_process = control.impacted_process.split(",")
    all_user_data = makepath(programdata,'Arduino15')

    # Installing the software
    print("Installing: %s" % bin_name)
    install_msi_if_needed(bin_name,
        properties='/qn ALLUSERS=1',
        killbefore=impacted_process,
        timeout=900
    )
    uninstallkey.remove(app_uninstallkey)
    copytree2('Arduino15',all_user_data)
    print('Restricting permissions on %s' % all_user_data)
    run(r'icacls "%s" /t /grant *S-1-5-21-3299883279-2723331061-3856246482-1728:(OI)(CI)M' % all_user_data) # groupe AD ELEVES (Get-ADGroup -Identity ELEVES | select Name, SID)
    run(r'icacls "%s" /t /grant *S-1-5-21-3299883279-2723331061-3856246482-1732:(OI)(CI)M' % all_user_data) # groupe AD PROFESSEUR (Get-ADGroup -Identity PROFESSEUR | select Name, SID)
    run(r'icacls "%s\\package_index.json" /inheritance:e /t /c' % all_user_data)
    run(r'icacls "%s\\package_index.json.sig" /inheritance:e /t /c' % all_user_data)

def session_setup():
    import tempfile
    pathparamsfile = makepath(tempfile.gettempdir(),'arduino-cli.yaml')
    currentuser = os.getlogin()
    configpath = makepath(r'c:\users',currentuser,'.arduinoIDE')
    data = r"""board_manager:
  additional_urls: []
daemon:
  port: "50051"
directories:
  data: C:\ProgramData\Arduino15
  downloads: C:\Users\%s\AppData\Local\Arduino15\staging
  user: C:\Users\%s\Documents\Arduino
library:
  enable_unsafe_install: false
locale: fr
logging:
  file: ""
  format: text
  level: info
metrics:
  addr: :9090
  enabled: true
output:
  no_color: false
sketch:
  always_export_binaries: false
updater:
  enable_notification: true
""" % (currentuser,currentuser)
    fichier = open(pathparamsfile, "w")
    fichier.write(data)
    fichier.close()
    mkdirs(configpath)
    filecopyto(pathparamsfile,configpath)
    remove_file(pathparamsfile)

def audit():
    if isfile(r'%s\Arduino\uninstall.exe' % programfiles32):
        print('Version précédente détectée')
        return "WARNING"
    else:
        return "OK"

def update_package():
    # Declaring local variables
    result = False
    proxies = get_proxies()
    if not proxies:
        proxies = get_proxies_from_wapt_console()
    app_name = control.name
    url = control.sources

    # Getting latest version from official website
    version_temp = bs_find_all(url, 'span', 'class', 'download-title',proxies=proxies)[0].string
    version = version_temp.split(' ')[+2]
    latest_bin = bin_name_string % version
    download_url = 'https://downloads.arduino.cc/arduino-ide/arduino-ide_%s_Windows_64bit.msi' % version

    print("Latest %s version is: %s" % (app_name, version))
    print("Download URL is: %s" % download_url)

    # Downloading latest binaries
    if not isfile(latest_bin):
        print("Downloading: %s" % latest_bin)
        wget(download_url, latest_bin, proxies=proxies)

        # Checking version from file
        version_from_file = get_version_from_binary(latest_bin)
        if not version_from_file.startswith(version) and version_from_file != '':
            print("Changing version to the version number of the binary (from: %s to: %s)" % (version, version_from_file))
            os.rename(latest_bin, bin_contains + version_from_file + ends_bin_name)
            version = version_from_file
        else:
            print("Binary file version corresponds to online version")

    # Changing version of the package
    if Version(version) > Version(control.get_software_version()):
        print("Software version updated (from: %s to: %s)" % (control.get_software_version(), Version(version)))
        result = True
    else:
        print("Software version up-to-date (%s)" % Version(version))
    control.version = '%s-%s' % (Version(version), control.version.split('-', 1)[-1])
    #control.set_software_version(version)
    control.save_control_to_wapt()

    # Deleting outdated binaries
    remove_outdated_binaries(version)

    # Validating update-package-sources
    return result

def get_proxies():
    if platform.python_version_tuple()[0] == '3':
        from urllib.request import getproxies
    else:
        from urllib import getproxies
    return getproxies()


def get_version_from_binary(filename):
    if filename.endswith('.msi'):
        return get_msi_properties(filename)['ProductVersion']
    else:
        return get_file_properties(filename)['ProductVersion']


def remove_outdated_binaries(version, list_extensions=['exe','msi','deb','rpm','dmg','pkg'], list_filename_contain=None):
    if type(list_extensions) != list:
        list_extensions = [list_extensions]
    if list_filename_contain:
        if type(list_filename_contain) != list:
            list_filename_contain = [list_filename_contain]
    list_extensions = ['.' + ext for ext in list_extensions if ext[0] != '.']
    for file_ext in list_extensions:
        for bin_in_dir in glob.glob('*%s' % file_ext):
            if not version in bin_in_dir:
                remove_file(bin_in_dir)
            if list_filename_contain:
                for filename_contain in list_filename_contain:
                    if not filename_contain in bin_in_dir:
                        remove_file(bin_in_dir)

def get_proxies_from_wapt_console():
    proxies = {}
    if platform.system() == 'Windows':
        waptconsole_ini_path = makepath(user_local_appdata(), 'waptconsole', 'waptconsole.ini')
    else:
        waptconsole_ini_path = makepath(user_home_directory(), '.config', 'waptconsole', 'waptconsole.ini')
    if isfile(waptconsole_ini_path):
        proxy_wapt = inifile_readstring(waptconsole_ini_path, 'global', 'http_proxy')
        if proxy_wapt:
            proxies = {'http': proxy_wapt, 'https': proxy_wapt}
    return proxies

def uninstall():
    run(r'"MsiExec.exe" /X%s /quiet' % app_uninstallkey,timeout=900)
    print(r'Uninstalling all_user_data')
    remove_tree(makepath(programdata,'Arduino15'))
control:

Código: Seleccionar todo

package           : wapt-arduino
version           : 2.0.0-1
architecture      : x64
section           : base
priority          : optional
name              : Arduino IDE
categories        : 
maintainer        : olaplanche
description       : The Arduino Integrated Development Environment is a cross-platform application that is written in functions from C and C++. It is used to write and upload programs to Arduino compatible boards, but also, with the help of third-party cores, other vendor development boards.
depends           : wapt-ftdi-vcp-drivers,wapt-arduino-drivers
conflicts         : 
maturity          : PROD
locale            : fr
target_os         : windows
min_wapt_version  : 
sources           : https://www.arduino.cc/en/software
installed_size    : 
impacted_process  : arduino
description_fr    : 
description_pl    : 
description_de    : 
description_es    : 
description_pt    : 
description_it    : 
description_nl    : 
description_ru    : 
audit_schedule    : 
editor            : Arduino.cc
keywords          : 
licence           : Free
homepage          : www.arduino.cc