diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8d71b84b50f494efbaf8a87df9399d6dcaf6f2d3..dceb45a021553586cfa5f5413bc9a9e0ab3af71f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -77,6 +77,16 @@ if (${QT_VERSION_MAJOR} STRLESS 6)
   endif()
 endif()
 
+if(MSVC)
+  set(DEFAULT_BUILD_TYPE "Debug")
+  if(NOT CMAKE_BUILD_TYPE)
+    message(STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.")
+    set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE
+        STRING "Choose the type of build." FORCE)
+  endif()
+  set(OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/x64/${CMAKE_BUILD_TYPE}")
+endif()
+
 # libjamiclient
 add_subdirectory(${LIBCLIENT_SRC_DIR})
 
diff --git a/INSTALL.md b/INSTALL.md
index d429c6122b6ba0dd16d392a80c8277a7838f12e6..3a298778a1c05dd27c31d53f6581bbdf24a12947 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -55,8 +55,8 @@ Then, you can build the project
 
 ### With build.py
 
-The build.py Jami installer uses **python3 (minimum v3.6)**.  If it's not installed,
-please install it.  Then run the following to initialize and update
+The build.py Jami installer uses **python3 (minimum v3.6)**. If it's not installed,
+please install it. Then run the following to initialize and update
 the submodules to set them at the top of their latest commit (ideal
 for getting the latest development versions; otherwise, you can use
 `git submodule update --init` then checkout specific commits for each
@@ -85,7 +85,7 @@ specify its path using the `--qt` flag, e.g.
 `./build.py --install --qt=/home/<username>/Qt/6.2.1/gcc_64`.
 
 Now you will have the daemon in `daemon/bin/jamid` and the client in
-`build/jami`.  You can now run Jami using:
+`build/jami`. You can now run Jami using:
 
 ```bash
 ./build/jami
@@ -163,11 +163,11 @@ Only 64-bit MSVC build can be compiled.
 
 - Download [Visual Studio](https://visualstudio.microsoft.com/) (versions 2019 or 2022). _See the SDK notes below._
 
-  |              | SDK          | Toolset                                              | MFC              |
-  | ------------ | ------------ | ---------------------------------------------------- | ---------------- |
-  | Requirement: | 10.0.18362.0 | V142 (VisualStudio 2019) / V143 (VisualStudio 2022)  | matching Toolset |
+  |              | SDK          | Toolset                                             | MFC              |
+  | ------------ | ------------ | --------------------------------------------------- | ---------------- |
+  | Requirement: | 10.0.18362.0 | V142 (VisualStudio 2019) / V143 (VisualStudio 2022) | matching Toolset |
 
-- Install Qt Vs Tools under extensions, and configure msvc2017_64 path under Qt Options. _See the Qt notes below._
+- Install Qt Vs Tools under extensions, and configure msvc2017*64 path under Qt Options. \_See the Qt notes below.*
 
   |                      | Qt Version |
   | -------------------- | ---------- |
@@ -212,8 +212,6 @@ Only 64-bit MSVC build can be compiled.
 
 ```bash
     python build.py --install
-    python extras\scripts\build-windows.py init
-    python extras\scripts\build-windows.py --qtver <your qt version>
 ```
 
 - Then you should be able to use the Visual Studio Solution file in client-qt folder **(Configuration = Release, Platform = x64)**
@@ -243,11 +241,11 @@ Only 64-bit MSVC build can be compiled.
 
 **Jami**
 
-- Make sure that daemon is built first.  Then,
+- Make sure that daemon is built first. Then,
 
-```bash
-    python extras\scripts\build-windows.py init
-    python extras\scripts\build-windows.py
+```
+    python extras\scripts\build-windows.py --init
+    python extras\scripts\build-windows.py --qtver <your qt version>
 ```
 
 Note: if your qt version is different than 6.2.3, you need to use `python extras\scripts\build-windows.py --qtver <your qt version>`.
@@ -298,7 +296,7 @@ Built client could be find in `build/Jami`
 - We currently use [GoogleTest](https://github.com/google/googletest) and [Qt Quick Test](https://doc.qt.io/qt-5/qtquicktest-index.html#introduction) in our product. To build and run tests, you could use the following command.
 
 ```
-    python extras\scripts\build-windows.py [runtests, pack]
+    python extras\scripts\build-windows.py --tests
 ```
 
 - Note that, for tests, the path of local storage files for jami will be changed based on following environment variables.
diff --git a/README.md b/README.md
index 7ba8da69875a36f7073bf90767904804263f61a6..6ba07cb3db1296217efc4ce97fe3fa9b836bed3a 100644
--- a/README.md
+++ b/README.md
@@ -12,25 +12,25 @@ Jami provides all its users a universal communication tool, autonomous, free, se
 
 For more information about the jami project, see the following:
 
-+ Main website: https://jami.net/
-+ Download: https://jami.net/download/
-+ Bug tracker: https://git.jami.net/
-+ Repositories: https://review.jami.net
+- Main website: https://jami.net/
+- Download: https://jami.net/download/
+- Bug tracker: https://git.jami.net/
+- Repositories: https://review.jami.net
 
 # Getting involved
 
-+ Browse our [current issues](https://git.jami.net/savoirfairelinux/jami-client-qt/issues), or file an issue.
-+ IRC: #jami on libera.chat
-+ ML: jami@gnu.org
-+ Documentation: https://docs.jami.net
-+ Localization happens on [Transifex](https://www.transifex.com/savoirfairelinux/jami/dashboard/)
-+ [Our contributions propositions](https://git.jami.net/groups/savoirfairelinux/-/epics/1) or [feature requests](https://git.jami.net/savoirfairelinux/ring-project/wikis/technical/4.3.-Features-requests) asked by the community
-+ Packaging: Feel free to contact us
+- Browse our [current issues](https://git.jami.net/savoirfairelinux/jami-client-qt/issues), or file an issue.
+- IRC: #jami on libera.chat
+- ML: jami@gnu.org
+- Documentation: https://docs.jami.net
+- Localization happens on [Transifex](https://www.transifex.com/savoirfairelinux/jami/dashboard/)
+- [Our contributions propositions](https://git.jami.net/groups/savoirfairelinux/-/epics/1) or [feature requests](https://docs.jami.net/developer/feature-requests.html) asked by the community
+- Packaging: Feel free to contact us
 
 ## Notes
 
-+ Coding style is managed by the clang-format, if you want to contribute, please use the pre-commit hook automatically installed with `./make-ring.py --init`
-+ We use gerrit for our review. Please read https://git.jami.net/savoirfairelinux/ring-project/wikis/tutorials/Working-with-gerrit if you want to submit patches.
+- Coding style is managed by the clang-format, if you want to contribute, please use the pre-commit hook automatically installed with `./build.py --init`
+- We use gerrit for our review. Please read about [working with Gerrit](https://docs.jami.net/developer/working-with-gerrit.html) if you want to submit patches.
 
 ## Build
 
diff --git a/build.py b/build.py
index 06b4d53e67940927339c18c6c4ed1f7ddf2dab66..556a631bbaa4bd046c26451a88d312f36018f662 100755
--- a/build.py
+++ b/build.py
@@ -347,7 +347,7 @@ def run_install(args):
                 ['python winmake.py -iv '
                  f'-s {args.sdk} -b daemon'])
         build_windows = 'extras/scripts/build-windows.py'
-        execute_script([f'python {build_windows} init'])
+        execute_script([f'python {build_windows} --init'])
         execute_script([f'python {build_windows}'])
         return True
 
diff --git a/extras/ci/client-qt-gnulinux/Jenkinsfile b/extras/ci/client-qt-gnulinux/Jenkinsfile
index 241f04076b5e644dc6fc3b81bb61056169ca0231..1c4e4f2567d6342c3db2dc24e91caa73948538ef 100644
--- a/extras/ci/client-qt-gnulinux/Jenkinsfile
+++ b/extras/ci/client-qt-gnulinux/Jenkinsfile
@@ -118,9 +118,8 @@ pipeline {
                                 """)
                                 // Run tests
                                 exec_cmd("""
-                                    cd ${dockerTopDir}
-                                    cd tests/qml/src
-                                    HOME=/tmp ../../../build/tests/qml_tests
+                                    cd ${dockerTopDir}/build/tests
+                                    HOME=/tmp ctest -j${cpuCount} -V -C Release
                                 """)
                             }
                         }
diff --git a/extras/scripts/build-windows.py b/extras/scripts/build-windows.py
index 97d2de0db28ee55273852f9bc14c27c59ee08244..580a6f7b0cfa068366577cdd81e73759d9564dfe 100644
--- a/extras/scripts/build-windows.py
+++ b/extras/scripts/build-windows.py
@@ -1,177 +1,214 @@
 #!/usr/bin/env python3
+"""
+Build, test, and package the project.
+
+This script provides methods to build the project, build and run qml tests,
+and package the project for Windows.
+
+usage: build.py [-h] [-a ARCH] [-c CONFIG] [-t] [-i] [-v] {pack} ...
+
+optional arguments:
+  -a ARCH, --arch ARCH  Sets the build architecture
+  -c CONFIG, --config CONFIG
+                        Sets the build configuration type
+  -t, --tests           Build and run tests
+  -i, --init            Initialize submodules
+  -v, --version         Show the version number and exit
+  -s, --skip-build      Only do packaging or run tests, skip building
+
+positional arguments:
+  {pack}
+
+usage: build.py pack [-h] [-s] (-m | -z)
+
+mutually exclusive required arguments:
+  -m, --msi         Build MSI installer
+  -z, --zip         Build ZIP archive
+
+examples:
+1.  build.py --init pack --msi      # Build the application from scratch and
+                                      an MSI installer
+2.  build.py --init --tests         # Build the application from scratch and
+                                      build and run tests
+    build.py pack --zip             # Generate a ZIP archive of the application
+                                      without building
+
+"""
 
-import tempfile
-import re
 import sys
 import os
 import subprocess
 import platform
 import argparse
 import multiprocessing
-import fileinput
-from enum import Enum
-
-qt_version_default = '6.2.3'
 
-vs_where_path = os.path.join(
-    os.environ['ProgramFiles(x86)'], 'Microsoft Visual Studio', 'Installer', 'vswhere.exe'
-)
 
-host_is_64bit = (False, True)[platform.machine().endswith('64')]
+# Qt information
+QT_VERSION = "6.2.3"
+if sys.platform == "win32":
+    QT_PATH = os.path.join("c:", os.sep, "Qt")
+    QT_KIT_PATH = "msvc2019_64"
+else:
+    QT_PATH = ""
+    QT_KIT_PATH = "clang_64"
+qt_root_path = os.getenv("QT_ROOT_DIRECTORY", QT_PATH)
+
+# Visual Studio helpers
+VS_WHERE_PATH = ""
+if sys.platform == "win32":
+    VS_WHERE_PATH = os.path.join(
+        os.environ["ProgramFiles(x86)"],
+        "Microsoft Visual Studio",
+        "Installer",
+        "vswhere.exe",
+    )
+WIN_SDK_VERSION = "10.0.18362.0"
+
+# Build/project environment information
+is_jenkins = "JENKINS_URL" in os.environ
+host_is_64bit = (False, True)[platform.machine().endswith("64")]
 this_dir = os.path.dirname(os.path.realpath(__file__))
-repo_root_dir = os.path.dirname(os.path.dirname(this_dir))
-build_dir = os.path.join(repo_root_dir, 'build')
-
-temp_path = os.environ['TEMP']
-openssl_include_dir = 'C:\\Qt\\Tools\\OpenSSL\\Win_x64\\include\\openssl'
-
-qt_path = os.path.join('c:', os.sep, 'Qt')
-qt_kit_path = 'msvc2019_64'
-qt_root_path = os.getenv('QT_ROOT_DIRECTORY', qt_path)
-
-# project path
-installer_project = os.path.join(
-    repo_root_dir, 'JamiInstaller', 'JamiInstaller.wixproj')
-unit_test_project = os.path.join(build_dir, 'tests', 'unittests.vcxproj')
-qml_test_project = os.path.join(build_dir, 'tests', 'qml_tests.vcxproj')
-
-# test executable command
-qml_test_exe = os.path.join(repo_root_dir, 'x64', 'test', 'qml_tests.exe -input ') + \
-    os.path.join(repo_root_dir, 'tests', 'qml')
-unit_test_exe = os.path.join(repo_root_dir, 'x64', 'test', 'unittests.exe')
+# the repo root is two levels up from this script
+repo_root_dir = os.path.abspath(os.path.join(this_dir, os.pardir, os.pardir))
+build_dir = os.path.join(repo_root_dir, "build")
 
 
 def execute_cmd(cmd, with_shell=False, env_vars=None, cmd_dir=repo_root_dir):
-    p = subprocess.Popen(cmd,
-                         shell=with_shell,
-                         stdout=sys.stdout,
-                         env=env_vars,
-                         cwd=cmd_dir)
-    _, _ = p.communicate()
-    return p.returncode
-
-
-def getLatestVSVersion():
+    """Execute a command with subprocess."""
+    proc = subprocess.Popen(
+        cmd,
+        shell=with_shell,
+        stdout=sys.stdout,
+        stderr=sys.stderr,
+        env=env_vars,
+        cwd=cmd_dir,
+    )
+    _, _ = proc.communicate()
+    return proc.returncode
+
+
+def get_latest_vs_version():
+    """Find the latest visual c++ compiler tools version."""
     args = [
-        '-latest',
-        '-products *',
-        '-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
-        '-property installationVersion'
+        "-latest",
+        "-products *",
+        "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
+        "-property installationVersion",
     ]
-    cmd = [vs_where_path] + args
-    output = subprocess.check_output(' '.join(cmd)).decode('utf-8')
+    cmd = [VS_WHERE_PATH] + args
+    output = subprocess.check_output(" ".join(cmd)).decode("utf-8")
     if output:
-        return output.splitlines()[0].split('.')[0]
+        return output.splitlines()[0].split(".")[0]
     else:
         return
 
 
-def findVSLatestDir():
+def find_latest_vs_dir():
+    """Find the latest visual c++ compiler tools path."""
     args = [
-        '-latest',
-        '-products *',
-        '-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
-        '-property installationPath'
+        "-latest",
+        "-products *",
+        "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
+        "-property installationPath",
     ]
-    cmd = [vs_where_path] + args
+    cmd = [VS_WHERE_PATH] + args
     output = subprocess.check_output(
-        ' '.join(cmd)).decode('utf-8', errors='ignore')
+        " ".join(cmd)).decode("utf-8", errors="ignore")
     if output:
         return output.splitlines()[0]
     else:
         return
 
 
-def findMSBuild():
-    filename = 'MSBuild.exe'
-    for root, _, files in os.walk(findVSLatestDir() + r'\\MSBuild'):
+def find_ms_build():
+    """Find the latest msbuild executable."""
+    filename = "MSBuild.exe"
+    vs_path = find_latest_vs_dir()
+    if vs_path is None:
+        return
+    for root, _, files in os.walk(os.path.join(vs_path, "MSBuild")):
         if filename in files:
             return os.path.join(root, filename)
 
 
-def getMSBuildArgs(arch, config_str, configuration_type=''):
+msbuild_cmd = find_ms_build()
+
+
+def get_ms_build_args(arch, config_str, toolset=""):
+    """Get an array of msbuild command args."""
     msbuild_args = [
-        '/nologo',
-        '/verbosity:minimal',
-        '/maxcpucount:' + str(multiprocessing.cpu_count()),
-        '/p:Platform=' + arch,
-        '/p:Configuration=' + config_str,
-        '/p:useenv=true']
-    if (configuration_type != ''):
-        msbuild_args.append('/p:ConfigurationType=' + configuration_type)
+        "/nologo",
+        "/verbosity:minimal",
+        "/maxcpucount:" + str(multiprocessing.cpu_count()),
+        "/p:Platform=" + arch,
+        "/p:Configuration=" + config_str,
+        "/p:useenv=true",
+    ]
+    if toolset != "":
+        msbuild_args.append("/p:PlatformToolset=" + toolset)
     return msbuild_args
 
 
-def getVSEnv(arch='x64', platform='', version=''):
-    env_cmd = 'set path=%path:"=% && ' + \
-        getVSEnvCmd(arch, platform, version) + ' && set'
-    p = subprocess.Popen(env_cmd,
-                         shell=True,
-                         stdout=subprocess.PIPE)
-    stdout, _ = p.communicate()
-    out = stdout.decode('utf-8', errors='ignore').split("\r\n")[5:-1]
-    return dict(s.split('=', 1) for s in out)
+def get_vs_env(arch="x64", _platform="", version=""):
+    """Get the vcvarsall.bat command."""
+    vs_env_cmd = get_vs_env_cmd(arch, _platform, version)
+    if vs_env_cmd is None:
+        return {}
+    env_cmd = f'set path=%path:"=% && {vs_env_cmd} && set'
+    proc = subprocess.Popen(env_cmd, shell=True, stdout=subprocess.PIPE)
+    stdout, _ = proc.communicate()
+    out = stdout.decode("utf-8", errors="ignore").split("\r\n")[5: -1]
+    return dict(s.split("=", 1) for s in out)
 
 
-def getVSEnvCmd(arch='x64', platform='', version=''):
-    vcEnvInit = [findVSLatestDir() + r'\VC\Auxiliary\Build\"vcvarsall.bat']
-    if platform != '':
-        args = [arch, platform, version]
+def get_vs_env_cmd(arch="x64", _platform="", version=""):
+    """Get the vcvarsall.bat command."""
+    vs_path = find_latest_vs_dir()
+    if vs_path is None:
+        return
+    vc_env_init = [os.path.join(
+        vs_path, "VC", "Auxiliary", "Build") + r'\"vcvarsall.bat']
+    if _platform != "":
+        args = [arch, _platform, version]
     else:
         args = [arch, version]
     if args:
-        vcEnvInit.extend(args)
-    vcEnvInit = 'call \"' + ' '.join(vcEnvInit)
-    return vcEnvInit
-
-
-def replace_necessary_vs_prop(project_path, toolset, sdk_version):
-    # force toolset
-    replace_vs_prop(project_path,
-                    'PlatformToolset',
-                    toolset)
-    # force unicode
-    replace_vs_prop(project_path,
-                    'CharacterSet',
-                    'Unicode')
-    # force sdk_version
-    replace_vs_prop(project_path,
-                    'WindowsTargetPlatformVersion',
-                    sdk_version)
-
-
-def build_project(msbuild, msbuild_args, proj, env_vars):
+        vc_env_init.extend(args)
+    vc_env_init = 'call "' + " ".join(vc_env_init)
+    return vc_env_init
+
+
+def build_project(msbuild_args, proj, env_vars):
+    """
+    Use msbuild to build a project.
+
+    Used specifically to build installer project and deps.
+    """
     args = []
     args.extend(msbuild_args)
     args.append(proj)
-    cmd = [msbuild]
+    cmd = [msbuild_cmd]
     cmd.extend(args)
-    if (execute_cmd(cmd, True, env_vars)):
-        print("Build failed when building ", proj)
+    if execute_cmd(cmd, True, env_vars):
+        print("Failed when building ", proj)
         sys.exit(1)
 
 
-def replace_vs_prop(filename, prop, val):
-    p = re.compile(r'(?s)<' + prop + r'\s?.*?>(.*?)<\/' + prop + r'>')
-    val = r'<' + prop + r'>' + val + r'</' + prop + r'>'
-    with fileinput.FileInput(filename, inplace=True) as file:
-        for line in file:
-            print(re.sub(p, val, line), end='')
-
-
 def init_submodules():
-    print('Initializing submodules...')
+    """Initialize any git submodules in the project."""
+    print("Initializing submodules...")
 
-    if (execute_cmd(['git', 'submodule', 'update', '--init'], False)):
-        print('Submodule initialization error.')
+    if execute_cmd(["git", "submodule", "update", "--init"], False):
+        print("Submodule initialization error.")
     else:
-        if (execute_cmd(['git', 'submodule', 'update', '--recursive'], False)):
-            print('Submodule recursive checkout error.')
+        if execute_cmd(["git", "submodule", "update", "--recursive"], False):
+            print("Submodule recursive checkout error.")
         else:
-            print('Submodule recursive checkout finished.')
+            print("Submodule recursive checkout finished.")
 
 
 def build_deps():
+    """Build the dependencies for the project."""
     print('Patching and building qrencode')
     apply_cmd = [
         'git',
@@ -183,163 +220,249 @@ def build_deps():
     qrencode_dir = os.path.join(repo_root_dir, '3rdparty', 'qrencode-win32')
     patch_file = os.path.join(repo_root_dir, 'qrencode-win32.patch')
     apply_cmd.append(patch_file)
-    print(apply_cmd)
-    if (execute_cmd(apply_cmd, False, None, qrencode_dir)):
+    if execute_cmd(apply_cmd, False, None, qrencode_dir):
         print("Couldn't patch qrencode-win32.")
 
     vs_env_vars = {}
-    vs_env_vars.update(getVSEnv())
+    vs_env_vars.update(get_vs_env())
+
+    msbuild_args = get_ms_build_args("x64", "Release-Lib")
 
-    msbuild = findMSBuild()
-    if not os.path.isfile(msbuild):
-        raise IOError('msbuild.exe not found. path=' + msbuild)
-    msbuild_args = getMSBuildArgs('x64', 'Release-Lib')
-    proj_path = os.path.join(qrencode_dir, 'qrencode-win32',
-                             'vc8', 'qrcodelib', 'qrcodelib.vcxproj')
+    proj_path = os.path.join(
+        qrencode_dir, "qrencode-win32", "vc8", "qrcodelib", "qrcodelib.vcxproj"
+    )
 
-    build_project(msbuild, msbuild_args, proj_path, vs_env_vars)
+    build_project(msbuild_args, proj_path, vs_env_vars)
 
 
-def build(config_str, qtver, tests=False):
+def cmake_generate(options, env_vars, cmake_build_dir):
+    """Generate the cmake project."""
+    print("Generating cmake project...")
+
+    # Pretty-print the options
+    print("Options:")
+    for option in options:
+        print("    " + option)
+
+    cmake_cmd = ["cmake", ".."]
+    cmake_cmd.extend(options)
+    if execute_cmd(cmake_cmd, False, env_vars, cmake_build_dir):
+        print("CMake generation error.")
+        return False
+    return True
+
+
+def cmake_build(config_str, env_vars, cmake_build_dir):
+    """Use cmake to build the project."""
+    print("Building cmake project...")
+
+    cmake_cmd = ["cmake", "--build", ".", "--config", config_str, "--", "-m"]
+    if execute_cmd(cmake_cmd, False, env_vars, cmake_build_dir):
+        print("CMake build error.")
+        return False
+    return True
+
+
+def build(config_str, qtver, tests):
+    """Use cmake to build the project."""
     print("Building with Qt " + qtver)
 
     vs_env_vars = {}
-    vs_env_vars.update(getVSEnv())
+    vs_env_vars.update(get_vs_env())
 
-    qt_dir = os.path.join(qt_root_path, qtver, qt_kit_path)
-    daemon_dir = os.path.join(repo_root_dir, 'daemon')
-    daemon_bin_dir = os.path.join(daemon_dir, 'build/x64/ReleaseLib_win32/bin')
+    # Get the Qt bin directory.
+    qt_dir = os.path.join(qt_root_path, qtver, QT_KIT_PATH)
+
+    # Get the daemon bin/include directories.
+    daemon_dir = os.path.join(repo_root_dir, "daemon")
+    daemon_bin_dir = os.path.join(
+        daemon_dir, "build", "x64", "ReleaseLib_win32", "bin")
 
     # We need to update the minimum SDK version to be able to
     # build with system theme support
     cmake_options = [
-        '-DWITH_DAEMON_SUBMODULE=ON',
-        '-DCMAKE_PREFIX_PATH=' + qt_dir,
-        '-DCMAKE_INSTALL_PREFIX=' + daemon_bin_dir,
-        '-DLIBJAMI_INCLUDE_DIR=' + daemon_dir + '\\src\\jami',
-        '-DCMAKE_SYSTEM_VERSION=10.0.18362.0'
+        "-DWITH_DAEMON_SUBMODULE=ON",
+        "-DCMAKE_PREFIX_PATH=" + qt_dir,
+        "-DCMAKE_INSTALL_PREFIX=" + daemon_bin_dir,
+        "-DLIBJAMI_INCLUDE_DIR=" + daemon_dir + "\\src\\jami",
+        "-DCMAKE_SYSTEM_VERSION=" + WIN_SDK_VERSION,
+        "-DCMAKE_BUILD_TYPE=" + config_str,
+        "-DENABLE_TESTS=" + str(tests).lower(),
+        "-DBETA=" + str((0, 1)[config_str == "Beta"]),
     ]
-    if tests:
-        cmake_options.append('-DENABLE_TESTS=true')
 
+    # Make sure the build directory exists.
     if not os.path.exists(build_dir):
         os.makedirs(build_dir)
 
-    cmd = ['cmake', '..']
-    if (config_str == 'Beta'):
-        cmake_options.append('-DBETA=1')
-
-    print('Generating…')
-    cmd.extend(cmake_options)
-    if (execute_cmd(cmd, False, vs_env_vars, build_dir)):
+    if not cmake_generate(cmake_options, vs_env_vars, build_dir):
         print("Cmake generate error")
         sys.exit(1)
 
-    print('Building…')
-    cmd = [
-        'cmake', '--build', '.',
-        '--config', 'Release',
-        '--', '-m'
-    ]
-    if (execute_cmd(cmd, False, vs_env_vars, build_dir)):
+    if not cmake_build(config_str, vs_env_vars, build_dir):
         print("Cmake build error")
         sys.exit(1)
 
 
-def run_tests(mute_jamid, output_to_files):
-    print('Running client tests')
-
-    test_exe_command_list = [qml_test_exe, unit_test_exe]
-
-    if mute_jamid:
-        test_exe_command_list[0] += ' -mutejamid'
-        test_exe_command_list[1] += ' -mutejamid'
-    if output_to_files:
-        test_exe_command_list[0] += ' -o ' + \
-            os.path.join(repo_root_dir, 'x64', 'test', 'qml_tests.txt')
-        test_exe_command_list[1] += ' > ' + \
-            os.path.join(repo_root_dir, 'x64', 'test', 'unittests.txt')
-
-    test_result_code = 0
-
-    # make sure that the tests are rendered offscreen
-    os.environ["QT_QPA_PLATFORM"] = 'offscreen'
-    os.environ["QT_QUICK_BACKEND"] = 'software'
-
-    for test_exe_command in test_exe_command_list:
-        if (execute_cmd(test_exe_command, True)):
-            test_result_code = 1
-    sys.exit(test_result_code)
+def run_tests(config_str):
+    """Run tests."""
+    print("Running client tests")
+
+    qt_dir = os.path.join(qt_root_path, QT_VERSION, QT_KIT_PATH)
+    os.environ["PATH"] += os.pathsep + os.path.join(qt_dir, 'bin')
+    os.environ["QT_QPA_PLATFORM"] = "offscreen"
+    os.environ["QT_QUICK_BACKEND"] = "software"
+    os.environ['QT_QPA_FONTDIR'] = os.path.join(
+        repo_root_dir, 'resources', 'fonts')
+    os.environ['QT_PLUGIN_PATH'] = os.path.join(qt_dir, 'plugins')
+    os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = os.path.join(
+        qt_dir, 'plugins', 'platforms')
+
+    tests_dir = os.path.join(build_dir, "tests")
+    if execute_cmd(["ctest", "-V", "-C", config_str],
+                   False, None, tests_dir):
+        print("Tests failed.")
+        sys.exit(1)
 
 
-def generate_msi_installer(config_str):
-    print('Generating application installer...')
+def generate_msi(version):
+    """Package MSI for Windows."""
+    print("Generating MSI installer...")
 
     vs_env_vars = {}
-    vs_env_vars.update(getVSEnv())
-    msbuild = findMSBuild()
-    if not os.path.isfile(msbuild):
-        raise IOError('msbuild.exe not found. path=' + msbuild)
-
-    msbuild_args = getMSBuildArgs('x64', config_str)
-
-    build_project(msbuild, msbuild_args, installer_project, vs_env_vars)
+    vs_env_vars.update(get_vs_env())
+    msbuild_args = get_ms_build_args("x64", "Release")
+    installer_dir = os.path.join(repo_root_dir, "JamiInstaller")
+    installer_project = os.path.join(installer_dir, "JamiInstaller.wixproj")
+    build_project(msbuild_args, installer_project, vs_env_vars)
+    msi_dir = os.path.join(installer_dir, "bin", "Release", "en-us")
+    msi_file_file = os.path.join(
+        msi_dir, "jami.release.x64.msi")
+    msi_version_file = os.path.join(
+        msi_dir, "jami-" + version + ".msi")
+    try:
+        os.rename(msi_file_file, msi_version_file)
+    except FileExistsError:
+        os.remove(msi_version_file)
+        os.rename(msi_file_file, msi_version_file)
+
+
+def generate_zip(version):
+    """Package archive for Windows."""
+    print('Generating 7z archive...')
+
+    # Generate 7z archive for Windows
+    app_output_dir = os.path.join(repo_root_dir, 'x64', 'Release')
+    app_files = os.path.join(app_output_dir, '*')
+
+    # TODO: exclude Jami.PDB, .deploy.stamp, and vc_redist.x64.exe
+
+    artifacts_dir = os.path.join(build_dir, 'artifacts')
+    if not os.path.exists(artifacts_dir):
+        os.makedirs(artifacts_dir)
+    zip_file = os.path.join(artifacts_dir, 'jami-' +
+                            version + '.7z')
+    cmd = ['7z', 'a', '-t7z', '-r', zip_file, app_files]
+    if execute_cmd(cmd, False):
+        print('Generating 7z error.')
+
+
+def get_version():
+    """Get version from git tag."""
+    version = ""
+    cmd = ["git", "describe", "--tags", "--abbrev=0"]
+    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+    out, _ = proc.communicate()
+    if out:
+        version = out.decode("utf-8").strip()
+    # transform slashes to dashes (if any)
+    version = version.replace("/", "-")
+    return version
 
 
 def parse_args():
-    ap = argparse.ArgumentParser(description="Client qt build tool")
-    subparser = ap.add_subparsers(dest="subparser_name")
-
-    ap.add_argument(
-        '-t', '--runtests', action='store_true',
-        help='Build and run tests')
-    ap.add_argument(
+    """Parse arguments."""
+    parser = argparse.ArgumentParser(description="Client build tool")
+    subparsers = parser.add_subparsers(dest="subcommand")
+
+    parser.add_argument(
+        "-a", "--arch", default="x64", help="Sets the build architecture")
+    parser.add_argument(
+        "-t", "--tests", action="store_true", help="Build and run tests")
+    parser.add_argument(
+        '-v', '--version', action='store_true',
+        help='Retrieve the current version')
+    parser.add_argument(
         '-b', '--beta', action='store_true',
         help='Build Qt Client in Beta Config')
-    ap.add_argument(
-        '-q', '--qtver', default=qt_version_default,
+    parser.add_argument(
+        '-q', '--qtver', default=QT_VERSION,
         help='Sets the version of Qmake')
-    ap.add_argument(
-        '-m', '--mute', action='store_true', default=False,
-        help='Mute jamid logs')
+    parser.add_argument(
+        "-i", "--init", action="store_true", help="Initialize submodules")
+    parser.add_argument(
+        "-s",
+        "--skip-build",
+        action="store_true",
+        default=False,
+        help="Only do packaging or run tests, skip build step")
 
-    subparser.add_parser('init')
-    subparser.add_parser('pack')
+    pack_arg_parser = subparsers.add_parser("pack")
+    pack_group = pack_arg_parser.add_mutually_exclusive_group(required=True)
+    pack_group.add_argument(
+        "-m", "--msi", action="store_true", help="Build MSI installer")
+    pack_group.add_argument(
+        "-z", "--zip", action="store_true", help="Build ZIP archive")
 
-    run_test = subparser.add_parser('runtests')
-    run_test.add_argument(
-        '-l', '--logtests', action='store_true', default=False,
-        help='Output tests log to files')
-
-    parsed_args = ap.parse_args()
-
-    return parsed_args
+    return parser.parse_args()
 
 
 def main():
+    """Parse options and run the appropriate command."""
     if not host_is_64bit:
-        print('These scripts will only run on a 64-bit Windows system for now!')
+        print("These scripts will only run on a 64-bit system for now.")
         sys.exit(1)
-
-    if int(getLatestVSVersion()) < 16:
-        print('These scripts require at least Visual Studio v16 2019!')
+    if sys.platform == "win32":
+        vs_version = get_latest_vs_version()
+        if vs_version is None or int(vs_version) < 15:
+            print("Visual Studio 2017 or later is required.")
+            sys.exit(1)
+
+    # Quit if msbuild was not found
+    if msbuild_cmd is None:
+        print("msbuild.exe not found")
         sys.exit(1)
 
     parsed_args = parse_args()
 
-    if parsed_args.subparser_name == 'init':
+    if parsed_args.version:
+        print(get_version())
+        sys.exit(0)
+
+    if parsed_args.init:
         init_submodules()
         build_deps()
-    elif parsed_args.subparser_name == 'pack':
-        config = ('Release', 'Beta')[parsed_args.beta]
-        generate_msi_installer(config)
-        sys.exit(1)
+        sys.exit(0)
+
+    config_str = ('Release', 'Beta')[parsed_args.beta]
+    skip_build = parsed_args.skip_build
+
+    if parsed_args.subcommand == "pack":
+        if not skip_build:
+            build(config_str, parsed_args.qtver, False)
+        elif parsed_args.msi:
+            generate_msi(get_version())
+        elif parsed_args.zip:
+            generate_zip(get_version())
     else:
-        config = ('Release', 'Beta')[parsed_args.beta]
-        build(config, parsed_args.qtver, parsed_args.runtests)
-        if parsed_args.runtests:
-            run_tests(parsed_args.mutejamid, parsed_args.outputtofiles)
+        if not skip_build:
+            build(config_str, parsed_args.qtver,
+                  parsed_args.tests)
+        if parsed_args.tests:
+            run_tests(config_str)
+
+    print("Done")
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     main()
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 09adc23dde90976547d113b0d661dfd610bc4848..3b9373c3a4eae916a662e688c5eb90fa42210149 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,4 +1,18 @@
-find_package(Qt${QT_VERSION_MAJOR} CONFIG REQUIRED QuickTest Test Widgets)
+cmake_minimum_required(VERSION 3.16)
+
+enable_testing(true)
+
+set(QT_TESTING_MODULES
+    ${QT_MODULES}
+    QuickControls2
+    QuickTest
+    Test
+    Widgets
+)
+find_package(Qt${QT_VERSION_MAJOR} CONFIG REQUIRED ${QT_TESTING_MODULES})
+foreach(MODULE ${QT_TESTING_MODULES})
+    list(APPEND QT_TEST_LIBS "Qt::${MODULE}")
+endforeach()
 
 if(MSVC)
     # Download and unpack googletest for windows
@@ -14,8 +28,7 @@ else()
     find_package(GTest REQUIRED)
 endif()
 
-enable_testing(true)
-set(QML_TEST_LIBS ${QT_LIBS} ${LIBCLIENT_NAME} Qt::QuickTest Qt::Test Qt::Widgets)
+set(QML_TEST_LIBS ${QT_LIBS} ${LIBCLIENT_NAME} ${QT_TEST_LIBS})
 set(TESTS_INCLUDES
     ${CMAKE_SOURCE_DIR}/src
     ${CMAKE_SOURCE_DIR}/tests/qml
@@ -29,168 +42,80 @@ target_compile_definitions(test_common_obj PRIVATE ENABLE_TESTS="ON")
 
 include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src)
 
-# QML tests
-add_executable(qml_tests
-               ${CMAKE_SOURCE_DIR}/tests/qml/main.cpp
-               ${QML_RESOURCES}
-               ${QML_RESOURCES_QML}
-               ${TEST_QML_RESOURCES}
-               ${SFPM_OBJECTS}
-               $<TARGET_OBJECTS:test_common_obj>)
+set(COMMON_TESTS_SOURCES
+    ${QML_RESOURCES}
+    ${QML_RESOURCES_QML}
+    $<TARGET_OBJECTS:test_common_obj>)
 
-target_link_libraries(qml_tests
-                      ${QML_TEST_LIBS}
-                      ${test_common_objects})
+if(MSVC)
+    list(APPEND WINDOWS_LIBS
+        ${QTWRAPPER_LIB}
+        ${RINGCLIENT_STATIC_LIB}
+        ${QRENCODE_LIB}
+        ${GNUTLS_LIB}
+        ${DRING_LIB}
+        ${WINDOWS_SYS_LIBS})
+
+    list(APPEND WINDOWS_INCLUDES
+        ${LRC_SRC_PATH}
+        ${DRING_SRC_PATH})
+else()
+    set(PTHREAD_LIB pthread)
+endif()
 
-target_compile_definitions(qml_tests PRIVATE ENABLE_TESTS="ON")
+string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE)
 
-# Unittests
-set(UNIT_TESTS_HEADER_FILES ${CMAKE_SOURCE_DIR}/tests/unittests/globaltestenvironment.h)
+set(QML_TESTS_SOURCE_FILES
+    ${CMAKE_SOURCE_DIR}/tests/qml/main.cpp
+    ${TEST_QML_RESOURCES}
+    ${SFPM_OBJECTS}
+    ${COMMON_TESTS_SOURCES})
 
 set(UNIT_TESTS_SOURCE_FILES
     ${CMAKE_SOURCE_DIR}/tests/unittests/main_unittest.cpp
     ${CMAKE_SOURCE_DIR}/tests/unittests/account_unittest.cpp
-    ${CMAKE_SOURCE_DIR}/tests/unittests/contact_unittest.cpp)
-
-add_executable(unittests
-               ${UNIT_TESTS_HEADER_FILES}
-               ${UNIT_TESTS_SOURCE_FILES}
-               ${QML_RESOURCES}
-               ${QML_RESOURCES_QML}
-               $<TARGET_OBJECTS:test_common_obj>)
+    ${CMAKE_SOURCE_DIR}/tests/unittests/contact_unittest.cpp
+    ${CMAKE_SOURCE_DIR}/tests/unittests/globaltestenvironment.h
+    ${COMMON_TESTS_SOURCES})
+
+set(ALL_TESTS_LIBS
+    ${QML_TEST_LIBS}
+    gtest
+    ${ringclient}
+    ${qrencode}
+    ${X11}
+    ${LIBNM_LIBRARIES}
+    ${LIBNOTIFY_LIBRARIES}
+    ${LIBGDKPIXBUF_LIBRARIES}
+    ${WINDOWS_LIBS})
+
+set(ALL_TESTS_INCLUDES
+    ${TESTS_INCLUDES}
+    ${LRC}/include/libringclient
+    ${LRC}/include
+    ${LIBNM_INCLUDE_DIRS}
+    ${LIBNOTIFY_INCLUDE_DIRS}
+    ${LIBGDKPIXBUF_INCLUDE_DIRS}
+    ${WINDOWS_INCLUDES})
+
+function(setup_test TEST_NAME TEST_SOURCES TEST_INPUT)
+    string(TOLOWER ${TEST_NAME} TEST_BINARY_NAME)
+    add_executable(${TEST_BINARY_NAME} ${TEST_SOURCES})
+    target_compile_definitions(${TEST_BINARY_NAME} PRIVATE ENABLE_TESTS="ON")
+    target_link_libraries(${TEST_BINARY_NAME} ${ALL_TESTS_LIBS})
+    target_include_directories(${TEST_BINARY_NAME} PUBLIC ${ALL_TESTS_INCLUDES})
+    if(MSVC)
+        set_target_properties(${TEST_BINARY_NAME} PROPERTIES
+            RUNTIME_OUTPUT_DIRECTORY_${BUILD_TYPE} ${OUTPUT_DIRECTORY})
+    endif()
+    add_test(NAME ${TEST_NAME} COMMAND ${TEST_BINARY_NAME} -input ${TEST_INPUT} -mutejamid)
+endfunction()
 
-target_link_libraries(unittests
-                      ${QML_TEST_LIBS}
-                      ${test_common_objects}
-                      gtest)
-
-target_compile_definitions(unittests PRIVATE ENABLE_TESTS="ON")
-
-if(MSVC)
-    include_directories(${LRC_SRC_PATH}
-                        ${DRING_SRC_PATH})
-
-    # QML tests
-    target_link_libraries(qml_tests
-                          ${QTWRAPPER_LIB}
-                          ${RINGCLIENT_STATIC_LIB}
-                          ${QRENCODE_LIB}
-                          ${GNUTLS_LIB}
-                          ${DRING_LIB}
-                          ${WINDOWS_SYS_LIBS})
-
-    target_include_directories(qml_tests PUBLIC
-                               ${TESTS_INCLUDES}
-                               ${LRC_SRC_PATH}
-                               ${DRING_SRC_PATH})
-
-    # output test executable files into test folder
-    set_target_properties(qml_tests
-        PROPERTIES
-        RUNTIME_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/x64/test"
-    )
+# QML tests
+setup_test(Qml_Tests
+    "${QML_TESTS_SOURCE_FILES}"
+    "${PROJECT_SOURCE_DIR}/tests/qml/src")
 
-    # POST_BUILD steps
-
-    # check time stamp
-    set(TIME_STAMP_FILE ".deploy.stamp")
-    add_custom_command(TARGET qml_tests POST_BUILD
-                       WORKING_DIRECTORY "$<TARGET_FILE_DIR:qml_tests>"
-                       COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
-                               -P ${PROJECT_SOURCE_DIR}/cmake/time_stamp_check.cmake)
-
-    # daemon deploy
-    add_custom_command(TARGET qml_tests POST_BUILD
-                       WORKING_DIRECTORY "$<TARGET_FILE_DIR:qml_tests>"
-                       COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
-                               -DCOPY_TO_PATH=$<TARGET_FILE_DIR:qml_tests>
-                               -DDRING_PATH=${DRING}
-                               -DPROJECT_ROOT_DIR=${PROJECT_SOURCE_DIR}
-                               -P ${PROJECT_SOURCE_DIR}/cmake/windows_daemon_deploy.cmake)
-
-    # Qt deploy for test qmls
-    add_custom_command(TARGET qml_tests POST_BUILD
-                       WORKING_DIRECTORY "$<TARGET_FILE_DIR:qml_tests>"
-                       COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
-                               -DWIN_DEPLOY_QT_PATH=${CMAKE_PREFIX_PATH}/bin
-                               -DQML_SRC_DIR=${CMAKE_SOURCE_DIR}/tests/qml
-                               -DEXE_NAME=$<TARGET_FILE:qml_tests>
-                               -DOFF_SCREEN_PLUGIN_REQUESTED=TRUE
-                               -DCOPY_TO_PATH=$<TARGET_FILE_DIR:qml_tests>/platforms
-                               -DOFF_SCREEN_PLUGIN_PATH=${CMAKE_PREFIX_PATH}/plugins/platforms
-                               -P ${PROJECT_SOURCE_DIR}/cmake/windows_qt_deploy.cmake)
-
-    # Qt deploy for src qmls
-    add_custom_command(TARGET qml_tests POST_BUILD
-                       WORKING_DIRECTORY "$<TARGET_FILE_DIR:qml_tests>"
-                       COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
-                               -DWIN_DEPLOY_QT_PATH=${CMAKE_PREFIX_PATH}/bin
-                               -DQML_SRC_DIR=${SRC_DIR}
-                               -DEXE_NAME=$<TARGET_FILE:qml_tests>
-                               -P ${PROJECT_SOURCE_DIR}/cmake/windows_qt_deploy.cmake)
-
-    # create time stamp
-    add_custom_command(TARGET qml_tests POST_BUILD
-                       WORKING_DIRECTORY "$<TARGET_FILE_DIR:qml_tests>"
-                       COMMAND ${CMAKE_COMMAND} -DTIME_STAMP_FILE=${TIME_STAMP_FILE}
-                               -P ${PROJECT_SOURCE_DIR}/cmake/time_stamp_create.cmake)
-
-    # Unittests
-    target_link_libraries(unittests
-                          ${QTWRAPPER_LIB}
-                          ${RINGCLIENT_STATIC_LIB}
-                          ${QRENCODE_LIB}
-                          ${GNUTLS_LIB}
-                          ${DRING_LIB}
-                          ${WINDOWS_SYS_LIBS})
-
-    target_include_directories(unittests PUBLIC
-                               ${TESTS_INCLUDES}
-                               ${LRC_SRC_PATH}
-                               ${DRING_SRC_PATH})
-
-    # output test executable files into test folder
-    set_target_properties(unittests
-        PROPERTIES
-        RUNTIME_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/x64/test"
-    )
-else()
-    include_directories(${LRC}/include/libringclient
-                        ${LRC}/include
-                        ${LIBNM_INCLUDE_DIRS}
-                        ${LIBNOTIFY_INCLUDE_DIRS}
-                        ${LIBGDKPIXBUF_INCLUDE_DIRS})
-
-    # QML tests
-    target_link_libraries(qml_tests
-                          ${ringclient}
-                          ${qrencode}
-                          ${X11}
-                          ${LIBNM_LIBRARIES}
-                          ${LIBNOTIFY_LIBRARIES}
-                          ${LIBGDKPIXBUF_LIBRARIES})
-
-    target_include_directories(qml_tests PUBLIC
-                               ${TESTS_INCLUDES}
-                               ${LRC}/include/libringclient
-                               ${LRC}/include)
-
-    add_test(NAME QmlTests COMMAND qml_tests -input ${PROJECT_SOURCE_DIR}/tests/qml/)
-
-    # Unittests
-    target_link_libraries(unittests
-                          ${ringclient}
-                          ${qrencode}
-                          pthread
-                          ${X11}
-                          ${LIBNM_LIBRARIES}
-                          ${LIBNOTIFY_LIBRARIES}
-                          ${LIBGDKPIXBUF_LIBRARIES})
-
-    target_include_directories(unittests PUBLIC
-                               ${TESTS_INCLUDES}
-                               ${LRC}/include/libringclient
-                               ${LRC}/include)
-
-    add_test(NAME UnitTests COMMAND unittests)
-endif()
+# Unit tests
+setup_test(Unit_Tests
+    "${UNIT_TESTS_SOURCE_FILES}" "")
\ No newline at end of file
diff --git a/tests/qml/main.cpp b/tests/qml/main.cpp
index 1a6e1f01e2faf371ced65df3939b7f1ffcd74ee1..50a53301274210a3b81197fdaa3fa8ab00f6213a 100644
--- a/tests/qml/main.cpp
+++ b/tests/qml/main.cpp
@@ -57,10 +57,6 @@ public:
 
         QFontDatabase::addApplicationFont(":/images/FontAwesome.otf");
 
-#if defined _MSC_VER && !COMPILE_ONLY
-        gnutls_global_init();
-#endif
-
         lrcInstance_.reset(
             new LRCInstance(nullptr, nullptr, "", connectivityMonitor_.get(), muteDring_));
         lrcInstance_->subscribeToDebugReceived();
diff --git a/tests/unittests/globaltestenvironment.h b/tests/unittests/globaltestenvironment.h
index 04797df4914e84ef0b930c615f6594b01397fcd6..ae69eb8557ef0d97817a2c26b01985f08ca8673b 100644
--- a/tests/unittests/globaltestenvironment.h
+++ b/tests/unittests/globaltestenvironment.h
@@ -45,10 +45,6 @@ public:
         settingsManager.reset(new AppSettingsManager(nullptr));
         systemTray.reset(new SystemTray(settingsManager.get(), nullptr));
 
-#if defined _MSC_VER
-        gnutls_global_init();
-#endif
-
         std::atomic_bool isMigrating(false);
         lrcInstance.reset(
             new LRCInstance(nullptr, nullptr, "", connectivityMonitor.get(), muteDring));