diff --git a/src/BUILD b/src/BUILD index b0365a1a18..342fd23738 100644 --- a/src/BUILD +++ b/src/BUILD @@ -2082,7 +2082,14 @@ cc_binary( ] + select({ "//conditions:default": [], "//src:windows" : ["main_windows.hpp", "main_windows.cpp",],}), - linkopts = LINKOPTS_ADJUSTED, + linkopts = LINKOPTS_ADJUSTED + select({ + "//conditions:default": [], + "//src:windows" : [ + "runtimeobject.lib", + "oleaut32.lib", + "ole32.lib", + ], + }), copts = COMMON_STATIC_LIBS_COPTS, deps = [ "//src:ovms_lib", diff --git a/src/main_windows.cpp b/src/main_windows.cpp index bee821292d..fe1925693f 100644 --- a/src/main_windows.cpp +++ b/src/main_windows.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,14 @@ #include #include #include +#pragma warning(push) +#pragma warning(disable : 28252 28253 6101) +#include +#include +#include +#include +#include +#pragma warning(pop) #include "main_windows.hpp" #include "module_names.hpp" @@ -107,8 +116,49 @@ inline std::wstring stringToWstring(const std::string& str, UINT codePage = CP_T return str2; } +// Short-term patch: look up the Tokenizers package directly by its known package name via +// PackageManager, regardless of whether/how it is declared as a dependency in any manifest. +// This avoids relying on Package::Current().Dependencies() at all. +static bool findInstalledPackageByName(const std::wstring& packageName, std::wstring& outInstalledPath) { + winrt::Windows::Management::Deployment::PackageManager packageManager; + for (const winrt::Windows::ApplicationModel::Package& pkg : packageManager.FindPackagesForUser(L"")) { + if (std::wstring(pkg.Id().Name().c_str()) == packageName) { + outInstalledPath = std::wstring(pkg.InstalledLocation().Path().c_str()); + return true; + } + } + return false; +} + +static void setOpenvinoTokenizersPathFromMsixDependencies() { + constexpr wchar_t PACKAGE_NAME[] = L"Intel.OpenVINO.Tokenizers.2026.3.0.0"; + constexpr wchar_t TOKENIZERS_RELATIVE_PATH[] = L"\\runtime\\bin\\intel64\\Release\\openvino_tokenizers.dll"; + + try { + std::wstring installedPath; + if (findInstalledPackageByName(PACKAGE_NAME, installedPath)) { + const std::wstring dllPath = installedPath + TOKENIZERS_RELATIVE_PATH; + SetEnvironmentVariableW(L"OPENVINO_TOKENIZERS_PATH_GENAI", dllPath.c_str()); + _wputenv_s(L"OPENVINO_TOKENIZERS_PATH_GENAI", dllPath.c_str()); + DEBUG_LOG("OPENVINO_TOKENIZERS_PATH_GENAI initialized from installed package lookup: " << wstringToString(dllPath)); + return; + } + DEBUG_LOG("Tokenizers MSIX package '" << wstringToString(std::wstring(PACKAGE_NAME)) << "' not found for current user. Keeping default behavior."); + } catch (const winrt::hresult_error& ex) { + // Not all deployments are packaged; keep default behavior when package metadata is unavailable. + std::ostringstream errMsg; + errMsg << "Failed to resolve Tokenizers MSIX dependency. HRESULT: 0x" << std::hex << std::uppercase + << static_cast(ex.code().value) << ", message: " << winrt::to_string(ex.message()); + DEBUG_LOG(errMsg.str()); + } +} + int main_windows(int argc, char** argv) { DEBUG_LOG("Windows Main - Entry"); + // Multi-threaded apartment: OVMS is a server process with no STA/message-loop dependency. + winrt::init_apartment(winrt::apartment_type::multi_threaded); + setOpenvinoTokenizersPathFromMsixDependencies(); + OvmsWindowsServiceManager::instance().ovmsParams.argc = argc; OvmsWindowsServiceManager::instance().ovmsParams.argv = argv; OvmsWindowsServiceManager::logParameters(argc, argv, "OVMS Main Argument");