Page 1 sur 1

[RESOLU] Paquet Arduino-IDE v2.0.2

Publié : 04 oct. 2022 - 11:38
par olaplanche
Bonjour,

- Le 24/11/2022 : Mise à jour du code pour la version 2.0.2 avec fonction uninstall pour désintaller proprement et modification du fichier de conf session-setup pour langue fr par défaut.

Je vous partage mon paquet Arduino-IDE v2.0.0 qui a demandé pas mal d'adaptation par rapport à la version 1.8.19...

Premièrement il faut savoir que la nouvelle version crée un dossier de donnée dans %localappdata% de chaque utilisateur. Il faut impérativement que l'utilisateur ait le contrôle total en lecture, écriture et exécution sur ce dossier pour le bon fonctionnement du logiciel.
Mon problème : J'utilise une SRP (Stratégie de restriction logiciel) qui interdit l'exécution de certains type de fichier depuis le profil utilisateur.
Il faut savoir également qu'à chaque première ouverture du logiciel par un utilisateur, une dossier Arduino15 va être créé dans %localappdata% et des librairies seront téléchargées. Ce dossier fait 346Mo, si un grand nombre d'utilisateurs utilise le logiciel, ça peut vite devenir la pagaille.
Et dernière chose, les pilotes arduino ne sont plus inclus dans cette version, il s'agit d'un téléchargement séparé. J'ai donc créé un paquet en dépendance : viewtopic.php?t=3222

Je vous propose donc un code qui copie le dossier Arduino15 (récupéré en amont dans le paquet) dans le dossier c:\ProgramData\Arduino15, modifie les droits sur ce dossier pour répondre aux prérequis. Il modifie également le fichier de conf du logiciel via la fonction session-setup afin de pointer vers le seul et unique dossier Arduino15 pour tous les utilisateurs.

Les utilisateurs auront donc les droits en écriture, lecture et exécution sur ce dossier qui est caché dans le dossier ProgramData et inaccessible aux utilisateurs via l'explorateur Windows et autorisé en exécution dans ma SRP.
J'ai également ajouté une fonction d'audit afin de détecter si la version précédente (<=1.8.19) est installée car cette version s'installe séparément.


Setup.py :

Code : Tout sélectionner

# -*- 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 :

Code : Tout sélectionner

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