WAPT Nvidia Driver Package

Questions about WAPT Packaging / Requests and help regarding Wapt packages.
Forum Rules
Community Forum Rules
* English support on www.reddit.com/r/wapt
* French community support is available on this forum
* Please prefix the topic title with [RESOLVED] if it is resolved.
* Please do not edit a topic that is tagged [RESOLVED]. Open a new topic referencing the old one.
* Specify the installed WAPT version, full version, and build number (2.2.1.11957 / 2.2.2.12337 / etc.) as well as the Enterprise/Discovery edition.
* Versions 1.8.2 and earlier are no longer supported. The only questions accepted regarding version 1.8.2 are related to upgrading to a supported version (2.1, 2.2, etc.).
* Specify the server OS (Linux/Windows) and version (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019).
* Specify the OS of the administration/package creation machine and the machine with the problematic agent, if applicable (Windows 7/10/11/Debian 11/etc.).
* Avoid asking multiple questions when opening a topic, otherwise it may be ignored. If there are multiple topics, open separate topics, preferably one after the other and not all at the same time (i.e., do not spam the forum).
* Include code snippets, screenshots, and other images directly in the post. Links to Pastebin, Bitly, and other third-party sites will be systematically removed.
* As with any community forum, support is provided voluntarily by members. If you require commercial support, you can contact Tranquil IT's sales department at 02.40.97.57.55
Answer
SeiyaGame
Messages: 13
Registration: May 25, 2023 - 3:19 p.m.

August 22, 2023 - 4:09 PM

Good morning,

I'd like to offer you a package I created for installing Nvidia drivers. The package is a template; users can choose which GPU driver they want to package!

I have performed the installation, uninstallation and update of the package.

Here is the file code setup.py :

Code: Select all

# -*- coding: utf-8 -*-
import re
from setuphelpers import *
from setupdevhelpers import *

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

"""

def sed(pattern, replace, source, count=0):
    """Reads a source file and writes the destination file.

    In each line, replaces pattern with replace.

    Args:
        pattern (str): pattern to match (can be re.pattern)
        replace (str): replacement str
        source  (str): input filename
        count (int): number of occurrences to replace   
    """

    fin = open(source, 'r')
    num_replaced = count

    dest_tmp = source + "_tmp"
    print(dest_tmp)
    fout = open(dest_tmp, 'w')

    for line in fin:
        out = re.sub(pattern, replace, line)
        fout.write(out)

        if out != line:
            num_replaced += 1
        if count and num_replaced > count:
            break
    try:
        fout.writelines(fin.readlines())
    except Exception as E:
        raise E

    fin.close()
    fout.close()

    shutil.move(dest_tmp, source) 

def install():
    # Declaring local variables
    bin_name = glob.glob("*.EXE")[0]
    driver_path = makepath(systemdrive, "NVIDIA")

    print("Extracting: " + bin_name)
    unzip_with_7zip(bin_name, driver_path)
    remove_file(bin_name)

    # Installing the software
    print("Installing: %s" % bin_name)

    install_exe_if_needed(
        makepath(driver_path, "setup.exe"),
        silentflags="-s -clean -noreboot -noeula",
        key="{B2FE1952-0186-46C3-BAEC-A80AA35AC5B8}_Display.Driver",
        min_version=control.get_software_version(),
        timeout=900,
    )

    print("Deletion of the driver folder")
    remove_tree(driver_path)

def uninstall():
    print(f'Uninstallation of {control.asrequirement()}')

    nvidia_display_nvx = "C:\\Program Files\\NVIDIA Corporation\\Installer2\\Display.Driver\\DisplayDriver.NVX"
    sed('uninstallReboot="true"', 'uninstallReboot="false"', nvidia_display_nvx, count=1)
    
    driversToUninstall = ["Display.Driver","HDAudio.Driver"]
    for driver in driversToUninstall:
        run(f"C:\\Windows\\SysWOW64\\RunDll32.EXE 'C:\\Program Files\\NVIDIA Corporation\\Installer2\\InstallerCore\\NVI2.DLL',UninstallPackage {driver} -silent")
Here is the file code update_package.py :

Code: Select all

# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
from typing import Union
from urllib.parse import urlparse, parse_qs
from setupdevhelpers import *
from setuphelpers import *
import waptguihelper
import re

def get_lang():
    lang_dict = {
        "en-us": 1,
        "en-uk": 2,
        "en-in": 3,
        "de": 9,
        "es": 10,
        "fr": 12,
        "it": 13,
        "pl": 14,
        "pt": 15,
        "ru": 16,
    }
    lang_list = []
    for entry in lang_dict:
        lang_list.append({"Value": lang_dict[entry], "Short Name": entry})

    return waptguihelper.grid_dialog("Select a language (Please select only one)", lang_list, waptguihelper.GRT_SELECTED)[0]

def get_whql():
    whql_dict = {
        "Recommended/Certified": 1,
        "Beta": 0,
        "All": '',
    }
    whql_list = []
    for entry in whql_dict:
        whql_list.append({"Value": whql_dict[entry], "Type": entry})
        
    return waptguihelper.grid_dialog("Select a type of driver (Please select only one)", whql_list, waptguihelper.GRT_SELECTED)[0]['Value']

def xml_to_dict(xml_data: str):

    # Parse XML data
    root = ET.fromstring(xml_data)

    result = []
    for lookup_value in root.findall('.//LookupValue'):
        name = lookup_value.find('Name').text
        value = int(lookup_value.find('Value').text)
        result.append({'Value': value, 'Name': name})

    return result

def api_lookup_value_search(type_id: Union[str, int], parent_id: Union[str, int] = None):
    url = f"https://www.nvidia.fr/Download/API/lookupValueSearch.aspx?TypeID={type_id}"

    if parent_id is not None:
        url += f"&ParentID={parent_id}"

    headers = {
        'Content-Type': 'text/xml; charset=utf-8'
    }

    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        return response.content
    except requests.HTTPError as e:
        print(f"An error occurred: {e}")
        return None

def get_product_type():
    return xml_to_dict(api_lookup_value_search(type_id=1))

def get_product_series(id_product: Union[str, int]):
    return xml_to_dict(api_lookup_value_search(type_id=2, parent_id=id_product))

def get_product(id_product: Union[str, int]):
    return xml_to_dict(api_lookup_value_search(type_id=3, parent_id=id_product))

def get_operating_system(id_product: Union[str, int]):
    return xml_to_dict(api_lookup_value_search(type_id=4, parent_id=id_product))

def make_download_url():
    
    product_type = waptguihelper.grid_dialog("Product Type (Please select only one)", get_product_type(), waptguihelper.GRT_SELECTED)[0]['Value']
    product_series = waptguihelper.grid_dialog("Product Series (Please select only one)", get_product_series(product_type), waptguihelper.GRT_SELECTED)[0]['Value']
    product = waptguihelper.grid_dialog("Product (Please select only one)", get_product(product_series), waptguihelper.GRT_SELECTED)[0]
    operating_sys = waptguihelper.grid_dialog("Operating System (Please select only one)", get_operating_system(product_series), waptguihelper.GRT_SELECTED)[0]
    lang = get_lang()
    whql = get_whql()

    # Hardcoded on nvidia website ...
    windows_list = ['Windows 10 64-bit', 'Windows Server 2022', 'Windows Server 2019', 'Windows Server 2016', 'Windows 11']
    product_type_list = [1, 3, 7, 11]

    dtcid = 1 if (operating_sys['Name'] in windows_list) and (product_type in product_type_list) else 0

    url_version = f"https://www.nvidia.fr/Download/processFind.aspx?psid={product_series}&pfid={product['Value']}&osid={operating_sys['Value']}" \
                  f"&lid={lang['Value']}&whql={whql}&lang={lang['Short Name']}&ctk=0&qnfslb=00&dtcid={dtcid}"
    
    return url_version

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

    if not control.sources:
        control.sources = make_download_url()
        control.save_control_to_wapt()

    url_version = control.sources

    # Getting latest version
    print("URL used is: %s" % url_version)
    for bs_search in bs_find_all(url_version, "tr", "id", "driverList", proxies=proxies, timeout=10):
        version_driver = bs_search.find_all('td')[2]
        version = re.search(r'(\d+(?:\.\d+)+)', version_driver.text).group(1)
        download_redirect = "https:" + bs_search.find('a').get('href')
        break
    
    button_href = bs_find(download_redirect, "btn_drvr_lnk_txt", proxies=proxies, timeout=10).find_parent('a').get('href')
    parsed_url = urlparse(button_href)
    query_params = parse_qs(parsed_url.query)
    path_download_url = query_params.get('url')[0]

    download_url = f"https://fr.download.nvidia.com{path_download_url}"
    latest_bin = download_url.split('/')[-1]

    print(f"Latest {app_name} version is: {version}")
    print(f"Download URL is: {download_url}")

    # Downloading latest binaries
    if not isfile(latest_bin):
        print(f"Downloading: {latest_bin}")
        wget(download_url, latest_bin, proxies=proxies)
    else:
        print(f"Binary is present: {latest_bin}")

    # Changing version of the package
    if Version(version) > Version(control.get_software_version()):
        print(f"Software version updated (from: {control.get_software_version()} to: {Version(version)})")
        result = True
    else:
        print("Software version up-to-date (%s)" % Version(version))
    
    control.set_software_version(version)
    control.save_control_to_wapt()

    # Deleting outdated binaries
    remove_outdated_binaries(version)

    # Validating or not update-package-sources
    return result

if __name__ == "__main__":
    pass
And finally, the file control :

Code: Select all

package           : loq-nvidia-driver-template
version           : 1.0-5
architecture      : x64
section           : base
priority          : optional
name              : Template Nvidia Driver
categories        : Drivers
maintainer        : Flavien Schelfaut (Loquidy)
description       : Template for Nvidia graphics card drivers
depends           : loq-7zip
conflicts         : 
maturity          : PROD
locale            : all
target_os         : windows
min_wapt_version  : 2.0
sources           :
installed_size    : 
impacted_process  : 
description_fr    : 
description_pl    : 
description_de    : 
description_es    : 
description_pt    : 
description_it    : 
description_nl    : 
description_ru    : 
audit_schedule    : 
editor            : Nvidia
keywords          : 
licence           : 
homepage          : https://www.nvidia.fr/Download/Find.aspx?lang=fr
package_uuid      : f6c6c352-ed8f-4dc1-86c2-540a58e5dbcb
valid_from        : 
valid_until       : 
forced_install_on : 
changelog         : 
min_os_version    : 10.0
max_os_version    : 
icon_sha256sum    : 
signer            : loqwapt
signer_fingerprint: b4bf538731a5e9de85fe3a5014052844fe130cb54afab01cd1aaf90f284bd72e
signature         : r/yg/Fz/pEqmbjiPupR+7HoafCLqfjv+ycGHTz+r7dRsMptL9w589y3O6rSg+qKSe9wKPWaI9g1X5WFh3Gh5CZBMOYCs02tIx4n9+B7/JHlitTm7qY2FMRh6T5mVZO9XecgV/Ex75deDvXVLw3GyUtJKnHhOn5JfPl/ldPYzQmtn6ap8ujGCqRGjIfBaa/bVhK19pgqka/6c0c52X0S83X3jj2avvAKXnyCYGipciIypgbNm6+TCKWUCjwIEQN6sXdekBlDZcQQAiJ8d8v0scqSVX2ljS+SbGnfobAbH8Vp5RWtvIqSXcGHOP2zRUeMcrLS2yYYyoLNgPJgFDWK+OA==
signature_date    : 2023-08-22T08:53:43.914722
signed_attributes : package,version,architecture,section,priority,name,categories,maintainer,description,depends,conflicts,maturity,locale,target_os,min_wapt_version,sources,installed_size,impacted_process,description_fr,description_pl,description_de,description_es,description_pt,description_it,description_nl,description_ru,audit_schedule,editor,keywords,licence,homepage,package_uuid,valid_from,valid_until,forced_install_on,changelog,min_os_version,max_os_version,icon_sha256sum,signer,signer_fingerprint,signature_date,signed_attributes
General information:

WAPT Server: Debian 11, version 2.4.0.14143, Enterprise Edition
Administration machine: Windows 11, WAPT version 2.4.0.14143
User avatar
dcardon
WAPT Expert
Messages: 1932
Registration: June 18, 2014 - 09:58
Location: Saint Sébastien sur Loire
Contact :

August 23, 2023 - 5:00 PM

Thanks so much for sharing, Flavien :-) ! I'll check with Jimmy about adding it to the store if that's okay with you.

Denis
Denis Cardon - Tranquil IT
Share your experiences on WAPT! Send us your blog and article URLs in the "Your Opinion of the forum, and we'll feature them on the WAPT
SeiyaGame
Messages: 13
Registration: May 25, 2023 - 3:19 p.m.

August 23, 2023 - 8:36 PM

I'd be happy to make it available to everyone :D !
The proxy section might need revision or improvement, as I haven't been able to test it.

Also, I have 2-3 other packages in development (AMD Driver Template, Jabra software, and the Charlemagne ...).
I'm hesitant to post the Charlemagne package because it's a bit complicated to maintain (there are at least 13 programs, each with dependencies, and 2 don't yet have a correct version number).
Answer