tis-microsoft-office-template

0-5
Run update_package to download the Microsoft Office of your choice
2126 downloads
Download
See build result See VirusTotal scan
tis-microsoft-office-template icon
  • package : tis-microsoft-office-template
  • name : Microsoft Office Template
  • version : 0-5
  • categories : Office
  • maintainer : WAPT Team,Tranquil IT,Pierre COSSON,Jimmy PELE
  • editor : Microsoft
  • licence : Proprietary
  • locale : all
  • target_os : windows
  • impacted_process : EXCEL,GROOVE,MSACCESS,MSPUB,ONENOTE,OUTLOOK,POWERPNT,WINWORD,GROOVE
  • architecture : all
  • signature_date : 2023-06-01 20:00
  • size : 11.47 Ko
  • installed_size : 2.36 Go
  • homepage : https://www.office.com/
  • conflicts :
package           : tis-microsoft-office-template
version           : 0-5
architecture      : all
section           : base
priority          : optional
name              : Microsoft Office Template
categories        : Office
maintainer        : WAPT Team,Tranquil IT,Pierre COSSON,Jimmy PELE
description       : Run update_package to download the Microsoft Office of your choice
depends           : 
conflicts         : tis-microsoft-access-2016-runtime,tis-microsoft-office-2016,tis-microsoft-office-2013
maturity          : PROD
locale            : all
target_os         : windows
min_wapt_version  : 2.1
sources           : https://www.microsoft.com/download/details.aspx?id=49117
installed_size    : 2362231960
impacted_process  : EXCEL,GROOVE,MSACCESS,MSPUB,ONENOTE,OUTLOOK,POWERPNT,WINWORD,GROOVE
description_fr    : 
description_pl    : 
description_de    : 
description_es    : 
description_pt    : 
description_it    : 
description_nl    : 
description_ru    : 
audit_schedule    : 
editor            : Microsoft
keywords          : office
licence           : Proprietary
homepage          : https://www.office.com/
package_uuid      : a32fb021-784e-42eb-a177-74bf398ab0a3
valid_from        : 
valid_until       : 
forced_install_on : 
changelog         : 
min_os_version    : 6.1
max_os_version    : 
icon_sha256sum    : 2ac98141bf5b6777083f2bcbeab3ab034c01dff77718e108774575aaaa54a144
signer            : Tranquil IT
signer_fingerprint: 8c5127a75392be9cc9afd0dbae1222a673072c308c14d88ab246e23832e8c6bb
signature         : WKVuni0nmEn5XRjlElilBzLGU/O+Jhr6a/5Qr4biMDWcQUunmi28ao4/oXAEWSY2kURi93J0Aw4HBrnmNebaNxQfp0Wq2Yjag+6sk4jFl8t8v++QeoMre+J1lxLFY1pm7EPSNqwEJnYjA78RyOODegDJmsUPq1A9k5g9akvHDp2sJr5YPpdlKOmYjbU/eBzKEaBrir8FC08GDDL1h2JR+xUfY5I41eUub7/ovClyQZnsRVlXBaxWCu8yBGfaKfGrrOXpuXCrqD62sVeLEAZQp0eSSNRUu+4Bt2XA6/Wp3cUpGEmatDXBO3tK6TlSEIpyU91vYR3MJ8XbYyz4AOURZQ==
signature_date    : 2023-06-01T20:00:12.393482
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
# -*- coding: utf-8 -*-
from setuphelpers import *
import tempfile

""" 
Ressources:
https://config.office.com/deploymentsettings
https://admx.help/?Category=Office2016&Policy=excel16.Office.Microsoft.Policies.Windows::L_SaveExcelfilesas

"""

app_uninstallkey = "O365ProPlusRetail - fr-fr"


def install():
    # Declaring local variables
    package_version = control.get_software_version()
    silentflags = "/configure configuration.xml"

    # uninstalling older versions of office
    uninstall_mso2013_if_needed("Office15.STANDARD")
    uninstall_mso2016_if_needed("Office16.STANDARD")

    # Installing the software
    install_exe_if_needed(
        "setup.exe",
        silentflags=silentflags,
        timeout=1200,
        accept_returncodes=[1641, 3010, 0],
        key=app_uninstallkey,
        min_version=package_version,
    )

    # TODO "setup.exe /customize configuration.xml if up-to-date"

    # Adding silent uninstall command
    quiet_uninstall = installed_softwares(uninstallkey=app_uninstallkey)[0]["uninstall_string"] + " DisplayLevel=False"
    if "OfficeClickToRun.exe" in quiet_uninstall:
        register_uninstall(
            uninstallkey=app_uninstallkey,
            quiet_uninstall_string=quiet_uninstall,
        )


def session_setup():
    print("Disabling: MSO telemetry")
    # https://admx.help/?Category=Office2016&Policy=office16.Office.Microsoft.Policies.Windows::L_OfficeOSMPreventedHostApplications
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedapplications", "wdsolution", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedapplications", "xlsolution", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedapplications", "pptsolution", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedapplications", "olksolution", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedapplications", "accesssolution", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedapplications", "projectsolution", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedapplications", "publishersolution", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedapplications", "visiosolution", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedapplications", "onenotesolution", 1)
    # https://admx.help/?Category=Office2016&Policy=office16.Office.Microsoft.Policies.Windows::L_OfficeOSMPreventedSolutionTypes
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedsolutiontypes", "documentfiles", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedsolutiontypes", "templatefiles", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedsolutiontypes", "comaddins", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedsolutiontypes", "appaddins", 1)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm\preventedsolutiontypes", "agave", 1)
    # https://admx.help/?Category=Office2016&Policy=office16.Office.Microsoft.Policies.Windows::L_EnableLogging
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm", "enablelogging", 0)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm", "enableupload", 0)
    registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\osm", "enablefileobfuscation", 1)
    # # https://admx.help/?Category=Office2016&Policy=office16.Office.Microsoft.Policies.Windows::L_Onlinecontentoptions
    # registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\common\internet", "useonlinecontent", 0)
    # # https://admx.help/?Category=Office2016&Policy=office16.Office.Microsoft.Policies.Windows::L_ServiceLevelOptions
    # registry_set(HKEY_CURRENT_USER, r"software\policies\microsoft\office\16.0\common\internet", "serviceleveloptions", 0)


def uninstall_mso2016_if_needed(uninstallkey):
    # Initializing variables
    silent_uninstall_file_path = makepath(tempfile.gettempdir(), "remove_o2016.xml")
    uninstall_configuration_xml_content = r"""<Configuration>
    <Remove All="TRUE">
    </Remove>
    <Display Level="none" CompletionNotice="No" SuppressModal="Yes" AcceptEula="Yes" />
    <Setting Id="SETUP_REBOOT" Value="Never" />
    <Setting Id="REBOOT" Value="ReallySuppress"/>
</Configuration>
"""
    # Modify XML
    with open(silent_uninstall_file_path, "w") as xml_file:
        xml_file.write(uninstall_configuration_xml_content)

    # Uninstalling Office if needed
    for to_uninstall in installed_softwares(uninstallkey=uninstallkey):
        print("Removing: %s (%s)" % (to_uninstall["name"], to_uninstall["version"]))
        killalltasks(control.get_impacted_process_list())
        if "OfficeClickToRun.exe" in to_uninstall["uninstall_string"]:
            app_uninstall_cmd = to_uninstall["uninstall_string"] + " DisplayLevel=False"
            run(app_uninstall_cmd)
            wait_uninstallkey_absent(to_uninstall["key"])
        else:
            run(to_uninstall["uninstall_string"] + ' /config "%s"' % silent_uninstall_file_path)
            wait_uninstallkey_absent(to_uninstall["key"])


def uninstall_mso2013_if_needed(uninstallkey):
    # Initializing variables
    silent_uninstall_file_path = makepath(tempfile.gettempdir(), "remove_o2013.xml")
    uninstall_configuration_xml_content = r"""<Configuration>
    <Remove All="TRUE">
    </Remove>
    <Display Level="none" CompletionNotice="No" SuppressModal="Yes" AcceptEula="Yes" />
    <Setting Id="SETUP_REBOOT" Value="Never" />
    <Setting Id="REBOOT" Value="ReallySuppress"/>
</Configuration>
"""
    # Modify XML
    with open(silent_uninstall_file_path, "w") as xml_file:
        xml_file.write(uninstall_configuration_xml_content)

    # Uninstalling Office if needed
    for to_uninstall in installed_softwares(uninstallkey=uninstallkey):
        print("Removing: %s (%s)" % (to_uninstall["name"], to_uninstall["version"]))
        killalltasks(control.get_impacted_process_list())
        run(to_uninstall["uninstall_string"] + ' /config "%s"' % silent_uninstall_file_path)
        wait_uninstallkey_absent(to_uninstall["key"])
# -*- coding: utf-8 -*-
from setuphelpers import *
import waptguihelper
import webbrowser


def update_package():
    # Define locale variable
    extract_path = "extract"
    package_updated = False

    # if not the first run it will use the last setup downloaded if you want to get an updated one you can remove setup.exe and relaunch the update package
    if not isfile("setup.exe"):
        waptguihelper.message_dialog(
            "You browser will open",
            "Please download Office Deployment Tool by clicking the download button",
        )
        webbrowser.open(control.sources)
        waptguihelper.message_dialog("Waiting for download", "Click OK when the download is complete", waptguihelper.ID_OK)
        # Copy to pkg
        installer_copy_path = waptguihelper.filename_dialog(
            "Please provide downloaded Office Deployment Tool to copy in this package",
            makepath(user_home_directory, "Downloads"),
            "",
            "EXE Files|*.exe",
        )

        # Extract Office Deployment Tool
        print("Copying: " + installer_copy_path)
        run(r"%s /extract:%s /quiet" % (installer_copy_path, extract_path))

        print("Extract Office Deployment Tool")
        filecopyto(".\\extract\\setup.exe", basedir)

    # if not the first run it will use the last XML used if you want to get a new one you can remove configuration.xml and relaunch the update package

    if not isfile("configuration.xml"):
        waptguihelper.message_dialog(
            "Your browser will open",
            "Please complete your deployment settings with the online Office Customization Tool and download it by clicking Export.\nNote that you can go back anytime on the online tool to edit your configuration (by clicking Import)",
        )
        webbrowser.open("https://config.office.com/deploymentsettings")
        waptguihelper.message_dialog("Waiting for download", "Click OK when the XML is completed and downloaded", waptguihelper.ID_OK)
        xml_configuration = waptguihelper.filename_dialog(
            "Please select your XML configuration file", basedir, "configuration.xml", "XML Files|*.xml"
        )  # makepath(user_home_directory, "Downloads")
        if not isfile("configuration.xml"):
            filecopyto(
                xml_configuration,
                basedir + "\\configuration.xml",
            )

    if isdir("extract"):
        remove_tree("extract")

    # removing the last sources folder downloaded
    if isdir("Office"):
        print("Removing last sources folder downloaded")
        remove_tree("Office")

    # Download Office with XML configuration
    print("Downloading Office with XML configuration")
    run("setup.exe /download configuration.xml", timeout=1200)  # DisplayLevel=Full # not working

    # Get version
    version = glob.glob("Office/Data/**/")[0].split(os.sep)[1]

    # 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)))
        package_updated = True
    else:
        print("Software version was up-to-date (%s)" % Version(version))
    control.set_software_version(version)
    control.save_control_to_wapt()

    # get product ID and language ID from configuration.xml parsing every line
    with open("configuration.xml", "r") as f:
        for line in f:
            if "OfficeClientEdition" in line:
                architecture = line.split('"')[1]
                print("OfficeClientEdition: %s" % architecture)
                if architecture == "64":
                    architecture = "x64"
                else:
                    architecture = "all"
            if "Product ID" in line:
                product_id = line.split('"')[1]
                print("Product ID: %s" % product_id)
            if "Language ID" in line:
                language_id = line.split('"')[1]
                print("Language ID: %s" % language_id)
                break

    if control.architecture != architecture:
        control.architecture = architecture
        control.save_control_to_wapt()

    # Asking pkg infos if needed
    if control.locale not in language_id and "-template" in control.package:
        control.locale = waptguihelper.input_dialog(control.package, "You may wanna change locale to: %s" % language_id.split("-")[0], "all")
        print("Changing locale to: %s in WAPT\\control" % control.locale)
        control.save_control_to_wapt()

    ask_control_categories()
    ask_control_package(control.package, "-template", remove_base_files=True)
    ask_control_name(control.name, " Template")
    ask_control_description(
        "update_package",
        "Office 365 E3 is a cloud-based suite of productivity apps and services with information protection and compliance capabilities included",
    )

    # changing uninstallkey:
    new_lines = []
    with open("setup.py", "r") as f:
        for line in f.readlines():
            if line.startswith("app_uninstallkey"):
                line = f'app_uninstallkey = "{product_id} - {language_id}"\n'
                print(f'uninstallkey in setup updated to app_uninstallkey = "{product_id} - {language_id}"\n')
            new_lines.append(line)
    with open("setup.py", "w") as f:
        f.writelines(new_lines)

    # Validating or not update-package-sources
    return package_updated


def ask_control_description(blank_str=None):
    """Requesting that the user supply package description for the control.description field

    Args:
        blank_str   (str): The description will be cleared if it includes the specified string to avoid using the template description (default: do not clear description)
    """
    old_control_description = control.description
    if not control.description:
        control.description = waptguihelper.input_dialog("Description", "Please fill the description", "")
    if blank_str is not None and blank_str in control.description:
        control.description = waptguihelper.input_dialog("Description", "Please fill the description", "")

    # Erase translations if description changed
    if old_control_description != control.description:
        for d in control.all_attributes:
            if d.startswith("description_"):
                control[d] = ""

    # Retire dot in the end of the string
    if control.description.endswith("."):
        control.description = control.description.rsplit(".", 1)[0]

    control.save_control_to_wapt()
    return control.description


def ask_control_categories():
    """Requesting that the user supply package categories for the control.categories field if empty or Template is selected"""

    if control.categories == "" or control.categories == "Template":
        categories = waptguihelper.grid_dialog(
            "Select package categories",
            [
                "Internet",
                "Utilities",
                "Messaging",
                "Security",
                "System and network",
                "Media",
                "Development",
                "Office",
                "Drivers",
                "Education",
                "Configuration",
                "CAD",
                "Template",
                "Dependency",
                "Extension",
            ],
            waptguihelper.GRT_SELECTED,
        )
        if categories:
            control.categories = ",".join([a["unknown"] for a in categories])
        else:
            control.categories = ""
        control.save_control_to_wapt()
    return control.categories


def ask_control_package(control_package=None, conditionnal_package_name=None, remove_base_files=False):
    """Requesting that the user provide a package name to be entered into the control.package field, and offering the possibility of removing the base files (icon.png and changelog.txt) for template package usage

    Args:
        control_package             (str)   : prefilled control_package (default: actual control_package)
        conditionnal_package_name   (str)   : only ask when the control.package contains conditionnal_package_name (default: always ask for control_package)
        remove_base_files           (bool)  : removes base files if parameter is True and conditionnal_package_name is provided (default: False)
    """
    if conditionnal_package_name is None or conditionnal_package_name in control.package:
        control.package = waptguihelper.input_dialog(
            control.package,
            "You can redefine the package name",
            control_package.replace(conditionnal_package_name, "") if conditionnal_package_name is not None else control_package,
        )
        control.save_control_to_wapt()

    # Removing template files
    if conditionnal_package_name in control.package and remove_base_files:
        if isfile("WAPT\\changelog.txt"):
            remove_file("WAPT\\changelog.txt")
        if isfile("WAPT\\icon.png"):
            remove_file("WAPT\\icon.png")
    return control.package


def ask_control_name(control_name=None, conditionnal_package_name=None):
    """Requesting that the user provide a package name to be entered into control.name field

    Args:
        control_name                (str)   : prefilled control_name (default: control.name)
        conditionnal_package_name   (str)   : only ask when the control.name contains conditionnal_package_name (default: always ask for control_name)
    """
    if conditionnal_package_name is None or conditionnal_package_name in control.name:
        control.name = waptguihelper.input_dialog(control.name, "You can redefine the name for the self-service", control_name)
        control.save_control_to_wapt()
    return control.name
3834363ff3077bd6249810374539693657d62b599b78b8d5f43deceae6b52580 : setup.py
15b085fc1f40aeb2324e10c03a89f3de019cb13a10db99c08c69bbbc56e3b3f8 : update_package.py
2ac98141bf5b6777083f2bcbeab3ab034c01dff77718e108774575aaaa54a144 : WAPT/icon.png
a5a97261381e1d0ad46ee15916abec9c2631d0201f5cc50ceb0197a165a0bbbf : WAPT/certificate.crt
c4d5e1967fa987b9afbfc4c12e6e59c2db7855a5eaba54204c5331a36871ff3f : WAPT/changelog.txt
280faf78416db5964ab1bd342cc343e409b353c464f6d440af42ccda7f21e850 : luti.json
2a5c303b2de1c9423382a8fc40420e66fcc5d5946dfc1a33ff7625d1d0c8283d : configuration-example.xml
01a93fe5611182be533d209908f8d4dbee759c6e62ea3b80eb8ca6fb9341fb51 : WAPT/control
0-5
===
The function uninstall_mso2013_if_needed() and uninstall_mso2016_if_needed() may have failed to execute properly
fix ask_*() functions