Send command line arguments through to the Flutter Engine on Windows (#68931)
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/runner/main.cpp.tmpl b/packages/flutter_tools/templates/app/windows.tmpl/runner/main.cpp.tmpl
index 6d2c86b..b3f8777 100644
--- a/packages/flutter_tools/templates/app/windows.tmpl/runner/main.cpp.tmpl
+++ b/packages/flutter_tools/templates/app/windows.tmpl/runner/main.cpp.tmpl
@@ -21,6 +21,12 @@
RunLoop run_loop;
flutter::DartProject project(L"data");
+
+ std::vector<std::string> command_line_arguments =
+ GetCommandLineArguments();
+
+ project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
+
FlutterWindow window(&run_loop, project);
Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/runner/utils.cpp b/packages/flutter_tools/templates/app/windows.tmpl/runner/utils.cpp
index 37501e5..d19bdbb 100644
--- a/packages/flutter_tools/templates/app/windows.tmpl/runner/utils.cpp
+++ b/packages/flutter_tools/templates/app/windows.tmpl/runner/utils.cpp
@@ -20,3 +20,45 @@
FlutterDesktopResyncOutputStreams();
}
}
+
+std::vector<std::string> GetCommandLineArguments() {
+ // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
+ int argc;
+ wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
+ if (argv == nullptr) {
+ return std::vector<std::string>();
+ }
+
+ std::vector<std::string> command_line_arguments;
+
+ // Skip the first argument as it's the binary name.
+ for (int i = 1; i < argc; i++) {
+ command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
+ }
+
+ ::LocalFree(argv);
+
+ return command_line_arguments;
+}
+
+std::string Utf8FromUtf16(const wchar_t* utf16_string) {
+ if (utf16_string == nullptr) {
+ return std::string();
+ }
+ int target_length = ::WideCharToMultiByte(
+ CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
+ -1, nullptr, 0, nullptr, nullptr);
+ if (target_length == 0) {
+ return std::string();
+ }
+ std::string utf8_string;
+ utf8_string.resize(target_length);
+ int converted_length = ::WideCharToMultiByte(
+ CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
+ -1, utf8_string.data(),
+ target_length, nullptr, nullptr);
+ if (converted_length == 0) {
+ return std::string();
+ }
+ return utf8_string;
+}
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/runner/utils.h b/packages/flutter_tools/templates/app/windows.tmpl/runner/utils.h
index d792603..3879d54 100644
--- a/packages/flutter_tools/templates/app/windows.tmpl/runner/utils.h
+++ b/packages/flutter_tools/templates/app/windows.tmpl/runner/utils.h
@@ -1,8 +1,19 @@
#ifndef RUNNER_UTILS_H_
#define RUNNER_UTILS_H_
+#include <string>
+#include <vector>
+
// Creates a console for the process, and redirects stdout and stderr to
// it for both the runner and the Flutter library.
void CreateAndAttachConsole();
+// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
+// encoded in UTF-8. Returns an empty std::string on failure.
+std::string Utf8FromUtf16(const wchar_t* utf16_string);
+
+// Gets the command line arguments passed in as a std::vector<std::string>,
+// encoded in UTF-8. Returns an empty std::vector<std::string> on failure.
+std::vector<std::string> GetCommandLineArguments();
+
#endif // RUNNER_UTILS_H_