Buen día,
Me topé con este tema por casualidad, de hecho hice un paquete para ZCO muy recientemente, basado en el de la tienda TIS.
Mi paquete es multiarquitectura e integra ambas versiones, 32 bits y 64 bits.
La razón es simple: en una máquina de 64 bits con una versión de 32 bits de Outlook instalada, el paquete de 64 bits fallará porque ZCO no se instalará.
Mi paquete detecta la presencia de Outlook de 32 bits e instala el ZCO correspondiente (seguramente existe una forma más limpia de detectar Office).
Además, defino algunos parámetros ZCO a través del registro (los mismos parámetros que se pueden usar para personalizar el MSI, pero no quería tener que hacerlo cada vez)

): deshabilitar actualizaciones, dirección y puerto del servidor, uso de SSL, deshabilitar alias en la GAL y deshabilitar la sincronización de firmas.
Para adaptar según las necesidades (hay otros parámetros personalizables en esta clave de registro).
Para solucionar el problema de que la clave de desinstalación cambia según el idioma, utilizo la función uninstall() que recupera la clave de desinstalación del ZCO instalado para desinstalarlo. Por lo tanto, no utilizo la función install_msi_if_needed().
Finalmente, la única restricción es que la versión del paquete debe coincidir con la versión de ZCO de 64 bits. Si publican números de versión diferentes para las dos arquitecturas, podría causar un problema (aunque creo que es poco probable).
Edición 01/03/2025:
- Se agregó una función de auditoría para agregar las claves de registro de Búsqueda de Windows del ZCO que se eliminaron después de una actualización automática de Office (personalmente configuré el parámetro "audit_schedule" en "10m" en el archivo de control); de lo contrario, el usuario que no es administrador recibe una solicitud de UAC cada vez que se inicia Outlook y la función de búsqueda deja de funcionar (consulte https://forums.zimbra.org/viewtopic.php?t=67734).
- Corrección de la configuración de ZCO a través del registro en Windows de 32 bits
Aquí está el código para setup.py:
Código: Seleccionar todo
# -*- coding: utf-8 -*-
from setuphelpers import *
from setupdevhelpers import *
def install():
# Check architecture and if Office is 32bits on 64bits system
regpath = r'SOFTWARE\Zimbra'
if is32() or isdir(makepath(programfiles32, r'Microsoft Office', r'root')):
print(r'INFO: x86 installation detected')
bin_name = 'ZimbraConnectorOLK_x86.msi'
if is64():
regpath = r'SOFTWARE\WOW6432Node\Zimbra'
else:
bin_name = 'ZimbraConnectorOLK_x64.msi'
installed_zco = installed_softwares('Zimbra Connector for Microsoft Outlook')
if not installed_zco or installed_zco[0]['version'] < Version(control.get_software_version(), 4) or WAPT.options.force :
try:
# Installing the software
run(r'msiexec /qn /norestart /i %s' % bin_name, timeout=600)
except Exception as e:
if e.returncode == 1603:
print(f'INFO: Microsoft Outlook needs to be installed.')
error(e)
else:
error(e)
else:
print('%s version %s is already installed, skipping...' % (control.name, installed_zco[0]['version']))
# Customize installation
with reg_openkey_noredir(HKEY_LOCAL_MACHINE, r'SOFTWARE\Zimbra', sam=KEY_WRITE, create_if_missing=True) as key:
reg_setvalue(key, 'SkipVersionUpgrade', '65535', REG_SZ) # disable auto-update
reg_setvalue(key, 'ZimbraServerName', 'smtp.mydomain.tld', REG_SZ) # Zimbra server name
reg_setvalue(key, 'ZimbraServerPort', 443, REG_DWORD) # Zimbra server port
reg_setvalue(key, 'ZimbraConnectionMethod', 1, REG_DWORD) # use SSL
reg_setvalue(key, 'GalSyncDisableAliases', 1, REG_DWORD) # disable alias in GAL
reg_setvalue(key, 'SigSyncEnabled', 0, REG_DWORD) # disable signature sync
def uninstall():
if installed_softwares('Zimbra Connector for Microsoft Outlook'):
key = installed_softwares('Zimbra Connector for Microsoft Outlook')[0]['key']
run('msiexec /qn /norestart /X %s' % key)
def audit():
audit_result = "OK"
# Check architecture and if Office is 32bits on 64bits system
regpath = r'SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Microsoft\Windows\Windows Search\Preferences'
if is64() and isdir(makepath(programfiles32, r'Microsoft Office', r'root')):
regpath = r'SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Windows\Windows Search\Preferences'
# Fix Windows Search ZCO registry key if needed
# https://wiki.zimbra.com/wiki/Summary_of_the_registry_keys_that_ZCO_uses
# https://forums.zimbra.org/viewtopic.php?t=67734
for key in [r'{D00FDE68-3E80-4f8c-899D-D9DD16BA7D1D}', r'{FA9628A0-F223-4d5d-B314-E01BC8100572}']:
if registry_readstring(HKEY_LOCAL_MACHINE, regpath, key) != "1":
print(r'Fixing Windows Search ZCO registry key %s...' % key)
registry_set(HKEY_LOCAL_MACHINE, regpath, key, 1, REG_DWORD)
audit_result = "WARNING"
return audit_result
def update_package():
# Declaring local variables
package_updated = False
proxies = get_proxies()
if not proxies:
proxies = get_proxies_from_wapt_console()
url = 'https://www.zimbra.com/product/addons/zimbra-connector-for-outlook-download/'
# Getting latest version from official sources
print('URL used is: %s' % url)
for arch in 'x86', 'x64':
print('Processing %s version...' % arch)
for bs_search in bs_find_all(url, 'a', 'rel', 'noopener', proxies=proxies):
if '_%s.msi' % arch in bs_search.get('href', ''):
download_url = bs_search['href']
latest_bin = download_url.split('/')[-1]
version = latest_bin.split('_')[1]
break
print('Latest %s %s version is: %s' % (control.name, arch, version))
print('Download URL for %s is: %s' % (arch, download_url))
# Downloading latest binaries
print('Downloading: %s' % latest_bin)
latest_bin = '%s_%s' % (latest_bin.split('_')[0], latest_bin.split('_')[2])
wget(download_url, latest_bin, proxies=proxies)
# Checking version from file
version_from_file = get_version_from_binary(latest_bin)
if Version(version_from_file, 4) == Version(version, 4):
print(f'INFO: Binary file version ({version_from_file}) corresponds to online version ({version})')
else:
error(f'ERROR: Binary file version ({version_from_file}) do NOT corresponds to online version ({version})')
# Changing version of the package
if Version(version, 4) > Version(control.get_software_version(), 4):
print('Software version updated (from: %s to: %s)' % (control.get_software_version(), Version(version)))
control.set_software_version(version)
control.save_control_to_wapt()
package_updated = True
else:
print('Software version up-to-date (%s)' % Version(version))
# Validating or not update-package-sources
return package_updated