Skip to content

Commit 6a185c1

Browse files
bryanoltmanfelangel
authored andcommitted
fix: use string-based Windows api to read version number (#92)
* fix: use string-based Windows api to read version number * support missing version label
1 parent 9e46ea1 commit 6a185c1

2 files changed

Lines changed: 45 additions & 21 deletions

File tree

engine/src/flutter/shell/common/shorebird/shorebird.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,11 @@ bool ConfigureShorebird(const ShorebirdConfigArgs& args,
132132
AppParameters app_parameters;
133133
// Combine version and version_code into a single string.
134134
// We could also pass these separately through to the updater if needed.
135-
auto release_version =
136-
args.release_version.version + "+" + args.release_version.build_number;
135+
auto release_version = args.release_version.version;
136+
if (!args.release_version.build_number.empty()) {
137+
release_version += "+" + args.release_version.build_number;
138+
}
139+
137140
app_parameters.release_version = release_version.c_str();
138141
app_parameters.code_cache_dir = code_cache_dir.c_str();
139142
app_parameters.app_storage_dir = app_storage_dir.c_str();

engine/src/flutter/shell/platform/windows/flutter_windows_engine.cc

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -269,36 +269,57 @@ int GetReleaseVersionAndBuildNumber(ReleaseVersion* release_version) {
269269
}
270270

271271
// Allocate memory for version info
272-
// std::vector<char> version_data(version_info_size);
273272
std::unique_ptr<char[]> version_data(new char[version_info_size]);
274273
if (!GetFileVersionInfoA(module_path, handle, version_info_size,
275274
version_data.get())) {
276275
return -1;
277276
}
278277

279-
// Get the version info structure
280-
VS_FIXEDFILEINFO* file_info = nullptr;
281-
UINT file_info_size = -1;
282-
if (!VerQueryValueA(version_data.get(), "\\",
283-
reinterpret_cast<LPVOID*>(&file_info), &file_info_size)) {
278+
// Adopted from
279+
// https://learn.microsoft.com/en-us/windows/win32/api/winver/nf-winver-verqueryvaluea
280+
// Get the translation table
281+
struct LANGANDCODEPAGE {
282+
WORD wLanguage;
283+
WORD wCodePage;
284+
}* lpTranslate;
285+
286+
UINT cbTranslate = 0;
287+
if (!VerQueryValueA(version_data.get(), "\\VarFileInfo\\Translation",
288+
(LPVOID*)&lpTranslate, &cbTranslate)) {
289+
FML_LOG(ERROR) << "Error: Unable to get translation info.";
284290
return -1;
285291
}
286292

287-
if (file_info) {
288-
// Extract version numbers
289-
DWORD major = HIWORD(file_info->dwProductVersionMS);
290-
DWORD minor = LOWORD(file_info->dwProductVersionMS);
291-
DWORD build = HIWORD(file_info->dwProductVersionLS);
292-
293-
char version[49];
294-
snprintf(version, sizeof(version), "%lu.%lu.%lu", major, minor, build);
295-
release_version->version = std::string(version);
296-
release_version->build_number =
297-
std::to_string(LOWORD(file_info->dwProductVersionLS));
298-
return kSuccess;
293+
// Construct the query string using the first translation found
294+
char subBlock[64];
295+
sprintf_s(subBlock, "\\StringFileInfo\\%04x%04x\\ProductVersion",
296+
lpTranslate[0].wLanguage, lpTranslate[0].wCodePage);
297+
298+
LPSTR versionString = nullptr;
299+
UINT size = 0;
300+
if (!VerQueryValueA(version_data.get(), subBlock, (LPVOID*)&versionString,
301+
&size)) {
302+
return -1;
303+
}
304+
305+
if (!versionString) {
306+
return -1;
307+
}
308+
309+
// The version string is in the format of "1.0.0+1", with the label ("+1")
310+
// being optional.
311+
auto version = std::string(versionString);
312+
auto plusPos = version.find("+");
313+
if (plusPos != std::string::npos) {
314+
auto semVer = version.substr(0, plusPos);
315+
auto patch = version.substr(plusPos + 1, version.length());
316+
release_version->version = semVer;
317+
release_version->build_number = patch;
318+
} else {
319+
release_version->version = version;
299320
}
300321

301-
return -1;
322+
return kSuccess;
302323
}
303324

304325
bool GetLocalAppDataPath(std::string& outPath) {

0 commit comments

Comments
 (0)