.. Reminder for header structure:
  Parts (H1)          : #################### with overline
  Chapters (H2)       : ******************** with overline
  Sections (H3)       : ====================
  Subsections (H4)    : --------------------
  Subsubsections (H5) : ^^^^^^^^^^^^^^^^^^^^
  Paragraphs (H6)     : """""""""""""""""""""

.. meta::
   :description: WAPT documentation version 2.7 Frequent problems and questions
   :keywords: WAPT packages, software installation, package errors, Python 3, GPO, uninstall, WAPT documentation

.. _wapt_faq_packages:

#####################
FAQ - Packages Issues
#####################

*************************************
Software deployment and configuration
*************************************

How can I uninstall software that was not installed with WAPT?
==============================================================

After deploying WAPT, you may need to remove legacy software that is already installed on your endpoints. WAPT can automate this process across multiple machines using a custom package containing Python code.

.. warning::

   This method only works for software installed at the system level.

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   **1. Identify and test the target software**

   Identify the software to uninstall and install it on a test machine to validate the package behavior.

   **2. Create an empty WAPT package**

   In the WAPT Console, navigate to:

   :menuselection:`Packages Inventory --> Make Package Template from Setup File --> Package Template --> Empty Package`

   **3. Add the uninstall code**

   Copy the code from :ref:`the software uninstallation example <Uninstalling_software>` into the package.

   Optionally, comment out the following condition if you want to uninstall all versions of the software, regardless of their version number:

   .. code-block:: python

      if Version(to_uninstall["version"]) < Version(control.get_software_version()):

   **4. Customize the package**

   Replace the software name in the code with the name of the application you want to uninstall.

   Optionally, add the software process name to the ``impacted-process`` field in the package's ``control`` file. For example, for WinSCP, use :file:`winscp.exe`.

   **5. Test the package**

   Run the package on your local machine and verify that the software is uninstalled as expected.

   **6. Build and upload the package**

   In the WAPT Console, navigate to:

   :menuselection:`Packages Inventory --> Import Package --> Build and Upload Package`

   Select the package you have edited.

   **7. Deploy the package**

   Deploy the package to the target machines to uninstall the software.


Why do WAPT configuration policies conflict with Group Policy settings?
=======================================================================

Some :abbr:`GPOs (Group Policy Objects)` enforced by the domain controller may conflict with configuration policies applied by WAPT.

When two policies manage the same setting, one may repeatedly overwrite the other. If WAPT audit scripts monitor that setting, the audit result may alternate between **|OK|** and **|ERROR|**.

For WAPT Enterprise users, using WAPT configuration packages to enforce policies can provide several advantages.

.. white_toggle::
   :titleen: Show explanation and recommendations
   :titlefr: Afficher l'explication et les recommandations

   **1. Use the WAPT agent's knowledge of OU membership**

   The :abbr:`OUs (Organizational Units)` displayed in the standard :abbr:`RSAT (Remote Server Administration Tool)` console may not always match the location that an endpoint reports in Active Directory.

   This can make it difficult to determine why a GPO has not been applied to a particular computer or group of computers. The WAPT agent reports the OUs to which the device belongs.

   **2. Audit policy application with WAPT**

   Windows does not provide a straightforward native way to report whether every GPO has been applied correctly.

   WAPT Enterprise audit scripts can verify whether a configuration has been applied and report the result in the WAPT Console as **|OK|** or **|ERROR|**.

   Adding ``print()`` statements to an audit script can also help identify why a configuration has failed.

   **3. Protect sensitive configuration data**

   GPO configuration files may expose confidential information, such as usernames and passwords, to interception.

   WAPT provides a mechanism for encrypting sensitive data so that it can only be decrypted by the intended endpoint. See :ref:`Encrypting sensitive data in a package <encryting_sensitive_data_in_package>`.

   **Recommendation**

   Whenever possible, use WAPT configuration packages instead of GPOs to deploy and audit configuration policies across your fleet.


How can I exclude specific workstations from a package deployed to an OU?
=========================================================================

When a package is deployed at the OU level, inheritance may cause it to apply to all relevant machines in that OU. If the package is a dependency or conflict, it is not possible to exclude selected machines natively from that inherited deployment.

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   There are two possible approaches.

   **Option 1: Install the package manually**

   If the package should be installed only on selected workstations within the OU, remove it from the OU-level deployment and install it manually on the target machines.

   **Option 2: Use a meta-package**

   Create a meta-package containing custom logic to determine which machines should receive the package and which should be excluded.

   See :ref:`meta-packages <meta-package>` for more information.


How can I install software that requires a system reboot?
=========================================================

Some applications require a system reboot before the installation process can continue. The following example shows how a package can detect whether the computer has rebooted and resume the installation accordingly.

.. white_toggle::
   :titleen: Show Python code example
   :titlefr: Afficher un exemple de code Python

   .. code-block:: python

      from setuphelpers import *

      def install():
          last_boot = str(host_metrics()['last_bootup_time']).rsplit('.', 1)[0]
          file_last_bootup_time = r'C:\last_bootup_time'

          if not isfile(file_last_bootup_time):
              print('First installation execution')

              # Insert here the code to be executed before the reboot.

              with open(file_last_bootup_time, 'w') as f:
                  f.write(last_boot)

              return "NEEDREBOOT"

          else:
              with open(file_last_bootup_time, 'r') as f:
                  data = f.read()

              if data == last_boot:
                  print("Installation already executed, but the system has not rebooted")
                  return "NEEDREBOOT"

              else:
                  print("Installation already executed and system rebooted; continuing")

                  # Insert here the code to be executed after the reboot.


********************
Python compatibility
********************


.. _python2to3:

Why must WAPT packages be updated from Python 2 to Python 3?
============================================================

Starting with WAPT 2.0, WAPT internals use Python 3. WAPT packages **MUST** therefore use Python 3-compatible syntax.

.. white_toggle::
   :titleen: Show the main syntax differences
   :titlefr: Afficher les principales différences de syntaxe

   .. list-table:: The principal syntax differences
      :header-rows: 1
      :widths: 80, 10, 10

      * - Syntax
        - Python 2
        - Python 3
      * - print
        - :code:`print 'Hello'`
        - :code:`print('Hello')`
      * - Unicode string
        - :code:`ur`
        - :code:`r`
      * - Operators
        - :code:`<> <=> !=`
        - :code:`!=`
      * - Windows registry access
        - :code:`_winreg`
        - :code:`winreg`

   For more details, see:

   - `Python-Future: compatible idioms <https://python-future.org/compatible_idioms.html>`_
   - `Tips and tricks for upgrading from Python 2 to Python 3 <https://blog.couchbase.com/tips-and-tricks-for-upgrading-from-python-2-to-python-3/>`_


Why does the WAPT service crash during package installation or removal?
=======================================================================

Some users have reported that the WAPT service crashes during software installation or removal. In the cases investigated, Bitdefender was blocking PowerShell execution, which caused the WAPT process to terminate.

.. white_toggle::
   :titleen: Show explanation and recommendation
   :titlefr: Afficher l'explication et la recommandation

   **1. Check antivirus logs and policies**

   Check whether the antivirus is blocking PowerShell or terminating WAPT-related processes.

   **2. Review the antivirus configuration**

   If the antivirus is responsible, review its policies and determine whether an appropriate exception can be configured in accordance with your organization's security requirements.

   **3. Check for similar behavior with other security products**

   This issue may also occur with other antivirus or endpoint protection products. Stay vigilant when investigating WAPT service crashes.


************************************
Creating and uploading WAPT packages
************************************

Packages with an available update are no longer displayed in red in the "Private Repositories" tab ?
====================================================================================================

Since WAPT 2.7, the red highlighting has been removed because it could be misleading. The update check takes into account all package capabilities (OS, version, language, architecture, etc.), which were not fully considered by the previous red highlighting.

This functionality has been properly reimplemented in the "Import from a repository" window. Simply select "Newer than in my repository" and "Compatible with known machines" to identify available updates accurately. More information about the processus :ref:`here <newer_version_package>`.


Why do I get a read-only database error when creating a package with PyScripter?
================================================================================

When you try to install a package from :program:`PyScripter`, the following error may appear:

.. image:: wapt-resources/windows_pyscripter_read-only-install-package_dialog-box.png
   :align: center
   :alt: OperationalError: attempt to write a read-only database

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   Launch :program:`PyScripter` using a :term:`Local Administrator` account, then retry the operation.


How can I re-sign packages after replacing a private key?
=========================================================

Packages in the repositories were signed using the former private key. After replacing that key, you **MUST** re-sign every package in the repository using the new key.

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   You can re-sign packages using either method:

   - :ref:`Using the WAPT Console <re_sign_package_gui>`
   - :ref:`Using the command line <re_sign_package_cmd>`


What should I do if a WAPT package is too large to upload?
==========================================================

A ``Stream write error`` may occur if the computer importing the package does not have enough free disk space.

During import, the package may be extracted, signed, built, and uploaded. This process can require approximately three times the package size in available disk space.

.. _package_too_big:

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   **1. Build the package locally**

   Build the WAPT package using :program:`PyScripter` or follow :ref:`the package build procedure <build_package>`.

   The package may be located in :file:`C:\waptdev`.

   **2. Upload the package manually**

   Download and install :program:`WinSCP`, or use an equivalent file transfer utility.

   Upload the package to the appropriate :ref:`repository location <repository_location>` for your WAPT repository version.

   **3. Recreate the repository index**

   After the upload is complete, recreate the :file:`Packages` index on the repository.

   Replace ``repository`` with the appropriate :ref:`repository location <repository_location>`:

   .. code-block:: bash

      wapt-scanpackages repository


Why does WAPT report that it is unable to create a file?
========================================================

.. figure:: wapt-resources/wapt-unable_to_create_file.png
   :align: center
   :alt: Unable to create a file

   WAPT - unable to create a file

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   Try clearing the WAPT Console cache in:

   ``AppData\Local\waptconsole\cache``


Why do I get an access violation when re-signing a WAPT package?
================================================================

.. image:: wapt-resources/wapt_console_package-resign-error_screen-item.png
   :align: center
   :alt: Signature processing has not ended successfully

An access violation error may occur when re-signing a large WAPT package.

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   Follow :ref:`the procedure for signing large WAPT packages <package_too_big>`.


************************************
Troubleshooting package installation
************************************


Why does a WAPT package fail to install even though the software is not installed?
==================================================================================

.. _common_problems_installing_a_package:

An error occurred while executing the package's :file:`setup.py`. The WAPT Console displays the error details, which can help identify the cause.

WAPT retries the installation during each :command:`upgrade` cycle until the package no longer returns an error.

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   **1. Investigate the error code**

   If WAPT returns an error code, search for the code to identify its meaning.

   For example, MSI error ``1618`` indicates that another installation is already running. Restarting the computer may resolve the issue.

   See the `Windows Installer error messages <https://learn.microsoft.com/en-us/windows/win32/msi/windows-installer-error-messages>`_ documentation for MSI error codes.

   **2. Reproduce the installation on the target computer**

   Go to the affected computer and run the package using the WAPT command-line utility. Check whether the software installs successfully.

   Once the silent installation has finished, do nothing else during the test. The goal is to reproduce the behavior of the WAPT Agent.

   **3. Check the execution context**

   If the package installs silently in the user context but fails through WAPT, the installer may not support installation in the **SYSTEM** context.

   **4. Run the installer manually if necessary**

   If the problem persists, launch the installation manually to reveal any explicit errors, such as missing dependencies.

   **5. Check for older software versions**

   Some installers cannot install over an older version. If necessary, explicitly remove older versions before installing the new one.


Why does a package fail with a timeout after 600 seconds?
=========================================================

Some packages return the following error in the WAPT Console:

.. code-block:: text

   Error timed out after seconds with output '600.0'

By default, WAPT waits 600 seconds for commands such as :command:`run` and :code:`install_msi_if_needed` to finish. If the installer does not complete within that period, WAPT stops the installation.

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   Increase the timeout for the installation command if the software is expected to take longer to install.

   For example, the following command sets the timeout to 1200 seconds:

   .. code-block:: python

      run('"setup.exe" /adminfile office2010noreboot.MSP', timeout=1200)

   This may be necessary for large applications such as Microsoft Office, SolidWorks, LibreOffice, CATIA, or Adobe Creative Suite.


Why does WAPT report that the software was installed but the uninstall key cannot be found?
===========================================================================================

Some packages return the following error in the WAPT Console:

.. code-block:: text

   XXX has been installed but the uninstall key can not be found.

WAPT uses Windows installer functions to install MSI and EXE binaries, such as :code:`install_msi_if_needed` and :code:`install_exe_if_needed`.

By default, WAPT accepts return codes ``0`` (success) and ``3010`` (restart required), then performs additional checks to verify that the installation succeeded.

These checks include verifying that the uninstall key exists and that the installed software version is equal to or greater than the version specified in the package's ``control`` file.

If these checks fail, WAPT marks the package as being in error and retries the installation during subsequent :code:`upgrade` cycles.

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   **1. Verify that the software is installed correctly**

   Before changing the package, physically check the affected computer and verify whether the software has actually been installed.

   If the installation failed, follow :ref:`the troubleshooting procedure for package installation <common_problems_installing_a_package>`.

   **2. Check the uninstall key and software version**

   If the software is installed correctly, the uninstall key or the version configured in the package may be incorrect.

   Retrieve the correct uninstall key and update the WAPT package accordingly.

   **3. Check MSI installer behavior**

   If the problem occurs with :code:`install_msi_if_needed`, the MSI installer may be returning an incorrect uninstall key.


Why does WAPT report that the uninstall key was found but the software version is incorrect?
============================================================================================

Some packages return the following error in the WAPT Console:

.. code-block:: text

   XXX has been installed and the uninstall key found but version is not good.

Functions such as :code:`install_msi_if_needed` and :code:`install_exe_if_needed` perform additional checks to verify that the installation succeeded.

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   **First, verify the installation**

   Check the affected computer and verify that the software is correctly installed. If it is not, follow :ref:`the troubleshooting procedure for package installation <common_problems_installing_a_package>`.

   **Case 1: The package uses ``install_msi_if_needed``**

   The MSI installer may provide incorrect version information, or the uninstall key may be incorrect.

   Run the following command to inspect the installed software information:

   .. code-block:: bash

      wapt-get list-registry

   If the returned key differs from the one configured in the installation section of :file:`setup.py`, you may not be able to use :code:`install_msi_if_needed`.

   Review the installation code, use :code:`run()`, and manage the installer checks and exceptions manually.

   **Case 2: The package uses ``install_exe_if_needed``**

   The version number supplied to :code:`install_exe_if_needed` may be incorrect.

   Review the package configuration and verify the uninstall key and software version using:

   .. code-block:: bash

      wapt-get list-registry

   If the command does not return a version, the installer may not provide an uninstall key or version information.

   There are two possible workarounds:

   **Option A: Provide a custom version function**

   Use the :code:`get_version` argument to retrieve the version from another uninstall key.

   .. code-block:: python

      def install():

          def versnaps2(key):
              return key['name'].replace('NAPS2 ', '')

          install_exe_if_needed(
              'naps2-5.3.3-setup.exe',
              silentflags='/VERYSILENT',
              key='NAPS2 (Not Another PDF Scanner 2)_is1',
              get_version=versnaps2
          )

   **Option B: Disable version checking**

   Setting an empty value for :code:`min_version` tells WAPT not to check the software version.

   .. code-block:: python

      min_version = ' '

   .. attention::

      With this method, **software versions are no longer checked during updates**.


Why does package registration fail with a DNSName A-label error?
================================================================

The following error may appear during package or host operations:

.. code-block:: text

   FATAL ERROR : ValueError: DNSName values should be passed as an A-label string. This means unicode characters should be encoded via a library like idna.

.. white_toggle::
   :titleen: Show solution
   :titlefr: Afficher la solution

   Check the workstation name and ensure that it does not contain special or non-ASCII characters.