Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 227 additions & 0 deletions Installer/Install.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Installer.h"
#include "RegKey.h"
#include <system_error>
#include <algorithm>


// Returns the exit code. Throws if failed to launch.
Expand Down Expand Up @@ -190,4 +191,230 @@ void CheckPhonemeConverters()
{
ReportError(ex.code().value());
}
}

// Parse command line parameter value
static std::wstring GetParameterValue(int argc, LPWSTR* argv, LPCWSTR paramName)
{
for (int i = 1; i < argc - 1; i++)
{
if (_wcsicmp(argv[i], paramName) == 0)
{
return argv[i + 1];
}
}
return L"";
}

// Check if parameter exists
static bool HasParameter(int argc, LPWSTR* argv, LPCWSTR paramName)
{
for (int i = 1; i < argc; i++)
{
if (_wcsicmp(argv[i], paramName) == 0)
{
return true;
}
}
return false;
}

// Apply configuration settings from command line
static void ApplyConfigurationSettings(int argc, LPWSTR* argv)
{
RegKey configKey, enumKey;

// Create registry keys
configKey.Create(HKEY_CURRENT_USER, L"Software\\NaturalVoiceSAPIAdapter", KEY_SET_VALUE);
enumKey.Create(HKEY_CURRENT_USER, L"Software\\NaturalVoiceSAPIAdapter\\Enumerator", KEY_SET_VALUE);

// Log level (0-6, default 2)
std::wstring logLevel = GetParameterValue(argc, argv, L"-loglevel");
if (!logLevel.empty())
{
DWORD level = _wtoi(logLevel.c_str());
if (level <= 6)
{
configKey.SetDword(L"LogLevel", level);
}
}

// Narrator voices
if (HasParameter(argc, argv, L"-no-narrator"))
{
enumKey.SetDword(L"NoNarratorVoices", 1);
}
else if (HasParameter(argc, argv, L"-enable-narrator"))
{
enumKey.SetDword(L"NoNarratorVoices", 0);
}

// Edge voices
if (HasParameter(argc, argv, L"-no-edge"))
{
enumKey.SetDword(L"NoEdgeVoices", 1);
}
else if (HasParameter(argc, argv, L"-enable-edge"))
{
enumKey.SetDword(L"NoEdgeVoices", 0);
}

// Azure voices
if (HasParameter(argc, argv, L"-no-azure"))
{
enumKey.SetDword(L"NoAzureVoices", 1);
}
else if (HasParameter(argc, argv, L"-enable-azure"))
{
enumKey.SetDword(L"NoAzureVoices", 0);
}

// Narrator voice path
std::wstring narratorPath = GetParameterValue(argc, argv, L"-narrator-path");
if (!narratorPath.empty())
{
enumKey.SetString(L"NarratorVoicePath", narratorPath.c_str());
}

// Azure key and region
std::wstring azureKey = GetParameterValue(argc, argv, L"-azure-key");
std::wstring azureRegion = GetParameterValue(argc, argv, L"-azure-region");
if (!azureKey.empty())
{
enumKey.SetString(L"AzureVoiceKey", azureKey.c_str());
}
if (!azureRegion.empty())
{
enumKey.SetString(L"AzureVoiceRegion", azureRegion.c_str());
}

// Language settings
if (HasParameter(argc, argv, L"-all-languages"))
{
enumKey.SetDword(L"EdgeVoiceAllLanguages", 1);
}
else
{
std::wstring languages = GetParameterValue(argc, argv, L"-languages");
if (!languages.empty())
{
enumKey.SetDword(L"EdgeVoiceAllLanguages", 0);
// Convert comma-separated to null-separated
std::vector<std::wstring> langList;
std::wstring temp;
for (wchar_t c : languages)
{
if (c == L',')
{
if (!temp.empty())
{
langList.push_back(temp);
temp.clear();
}
}
else
{
temp.push_back(c);
}
}
if (!temp.empty())
{
langList.push_back(temp);
}
enumKey.SetMultiStringList(L"EdgeVoiceLanguages", langList);
}
}
}

void SilentInstall(int argc, LPWSTR* argv)
{
// Apply configuration settings first
ApplyConfigurationSettings(argc, argv);

// Determine which architectures to install
bool install32 = true;
bool install64 = Is64BitSystem();

// Check for architecture-specific parameters
if (HasParameter(argc, argv, L"-32bit-only"))
{
install32 = true;
install64 = false;
}
else if (HasParameter(argc, argv, L"-64bit-only"))
{
install32 = false;
install64 = Is64BitSystem();
}

// Install 32-bit version
if (install32)
{
try
{
Register(false);
}
catch (const std::system_error&)
{
// In silent mode, we still throw to let the caller handle it
throw;
}
}

// Install 64-bit version
if (install64)
{
try
{
Register(true);
}
catch (const std::system_error&)
{
// In silent mode, we still throw to let the caller handle it
throw;
}
}

// Check and install phoneme converters if needed
if (!HasParameter(argc, argv, L"-no-phoneme-converters"))
{
HKEY hKey;
bool hasConverters = true;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\PhoneConverters\\Tokens\\Universal",
0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS)
{
RegCloseKey(hKey);
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\PhoneConverters\\Tokens\\Universal",
0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
{
RegCloseKey(hKey);
}
else
hasConverters = false;
}
else
hasConverters = false;

if (!hasConverters)
{
try
{
if (Is64BitSystem())
AddToRegistry(L"x64\\PhoneConverters.reg");
else
AddToRegistry(L"x86\\PhoneConverters.reg");
}
catch (const std::system_error&)
{
// Ignore errors in silent mode for phoneme converters
}
}
}
}

void SilentUninstall()
{
Unregister(false);
if (Is64BitSystem())
Unregister(true);
}
8 changes: 4 additions & 4 deletions Installer/Installer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,29 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<YY_Thunks_File>YY_Thunks_for_WinXP.obj</YY_Thunks_File>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<YY_Thunks_File>YY_Thunks_for_WinXP.obj</YY_Thunks_File>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<YY_Thunks_File>YY_Thunks_for_WinXP.obj</YY_Thunks_File>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<YY_Thunks_File>YY_Thunks_for_WinXP.obj</YY_Thunks_File>
Expand Down
Loading