Streamline Windows build process (#32783)

Allows Windows builds to use the same structure and script as Linux
builds now use, calling into tool_backend to manage copying resources to
the project directory and building the bundle.

Also switches from expecting name_update.bat to expecting flutter\exe_filename
to be written during the build, as with the recent changes to the macOS build, to
reduce the amount of boilerplate needed in a windows\ project directory.
diff --git a/packages/flutter_tools/bin/tool_backend.bat b/packages/flutter_tools/bin/tool_backend.bat
new file mode 100644
index 0000000..5a6abaf
--- /dev/null
+++ b/packages/flutter_tools/bin/tool_backend.bat
@@ -0,0 +1,9 @@
+:: Copyright 2019 The Chromium Authors. All rights reserved.
+:: Use of this source code is governed by a BSD-style license that can be
+:: found in the LICENSE file.
+@echo off
+
+set FLUTTER_BIN_DIR=%FLUTTER_ROOT%\bin
+set DART_BIN_DIR=%FLUTTER_BIN_DIR%\cache\dart-sdk\bin
+
+"%DART_BIN_DIR%\dart" "%FLUTTER_ROOT%\packages\flutter_tools\bin\tool_backend.dart" %*
diff --git a/packages/flutter_tools/bin/tool_backend.dart b/packages/flutter_tools/bin/tool_backend.dart
index e264ad3..96322f2 100644
--- a/packages/flutter_tools/bin/tool_backend.dart
+++ b/packages/flutter_tools/bin/tool_backend.dart
@@ -5,7 +5,7 @@
 import 'dart:io'; // ignore: dart_io_import.
 import 'package:path/path.dart' as path; // ignore: package_path_import.
 
-/// Executes the required flutter tasks for a linux build.
+/// Executes the required flutter tasks for a desktop build.
 Future<void> main(List<String> arguments) async {
   final String targetPlatform = arguments[0];
   final String buildMode = arguments[1];
@@ -26,9 +26,9 @@
 This engine is not compatible with FLUTTER_BUILD_MODE: '$buildMode'.
 You can fix this by updating the LOCAL_ENGINE environment variable, or
 by running:
-  flutter build linux --local-engine=host_$buildMode
+  flutter build <platform> --local-engine=host_$buildMode
 or
-  flutter build linux --local-engine=host_${buildMode}_unopt
+  flutter build <platform> --local-engine=host_${buildMode}_unopt
 ========================================================================
 ''');
     exit(1);
@@ -39,6 +39,9 @@
     case 'linux-x64':
       cacheDirectory = 'linux/flutter';
       break;
+    case 'windows-x64':
+      cacheDirectory = 'windows/flutter';
+      break;
     default:
       stderr.write('Unsupported target platform $targetPlatform');
       exit(1);
diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart
index c841d54..8c8e94f 100644
--- a/packages/flutter_tools/lib/src/build_info.dart
+++ b/packages/flutter_tools/lib/src/build_info.dart
@@ -326,6 +326,8 @@
       return TargetPlatform.darwin_x64;
     case 'linux-x64':
       return TargetPlatform.linux_x64;
+    case 'windows-x64':
+      return TargetPlatform.windows_x64;
     case 'web':
       return TargetPlatform.web;
   }
@@ -397,6 +399,11 @@
   return fs.path.join(getBuildDirectory(), 'linux');
 }
 
+/// Returns the Windows build output directory.
+String getWindowsBuildDirectory() {
+  return fs.path.join(getBuildDirectory(), 'windows');
+}
+
 /// Returns the Fuchsia build output directory.
 String getFuchsiaBuildDirectory() {
   return fs.path.join(getBuildDirectory(), 'fuchsia');
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart
index 8ac323e..0032d10 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -596,15 +596,19 @@
 
   Directory get _editableDirectory => project.directory.childDirectory('windows');
 
+  Directory get _cacheDirectory => _editableDirectory.childDirectory('flutter');
+
   /// Contains definitions for FLUTTER_ROOT, LOCAL_ENGINE, and more flags for
   /// the build.
-  File get generatedPropertySheetFile => _editableDirectory.childDirectory('flutter').childFile('Generated.props');
+  File get generatedPropertySheetFile => _cacheDirectory.childFile('Generated.props');
 
   // The MSBuild project file.
   File get vcprojFile => _editableDirectory.childFile('Runner.vcxproj');
 
-  // Note: The name script file exists as a temporary shim.
-  File get nameScript => _editableDirectory.childFile('name_output.bat');
+  /// The file where the VS build will write the name of the built app.
+  ///
+  /// Ideally this will be replaced in the future with inspection of the project.
+  File get nameFile => _cacheDirectory.childFile('exe_filename');
 }
 
 /// The Linux sub project.
diff --git a/packages/flutter_tools/lib/src/windows/application_package.dart b/packages/flutter_tools/lib/src/windows/application_package.dart
index 01ece5f..5832945 100644
--- a/packages/flutter_tools/lib/src/windows/application_package.dart
+++ b/packages/flutter_tools/lib/src/windows/application_package.dart
@@ -7,8 +7,6 @@
 import '../application_package.dart';
 import '../base/common.dart';
 import '../base/file_system.dart';
-import '../base/io.dart';
-import '../base/process_manager.dart';
 import '../build_info.dart';
 import '../project.dart';
 
@@ -61,14 +59,16 @@
 
   @override
   String executable(BuildMode buildMode) {
-    final ProcessResult result = processManager.runSync(<String>[
-      project.nameScript.path,
-      buildMode == BuildMode.debug ? 'debug' : 'release',
-    ]);
-    if (result.exitCode != 0) {
-      throwToolExit('Failed to find Windows project name');
+    final File exeNameFile = project.nameFile;
+    if (!exeNameFile.existsSync()) {
+      throwToolExit('Failed to find Windows executable name');
     }
-    return result.stdout.toString().trim();
+    return fs.path.join(
+        getWindowsBuildDirectory(),
+        'x64',
+        buildMode == BuildMode.debug ? 'Debug' : 'Release',
+        'Runner',
+        exeNameFile.readAsStringSync().trim());
   }
 
   @override
diff --git a/packages/flutter_tools/lib/src/windows/build_windows.dart b/packages/flutter_tools/lib/src/windows/build_windows.dart
index 985f9b7..776d864 100644
--- a/packages/flutter_tools/lib/src/windows/build_windows.dart
+++ b/packages/flutter_tools/lib/src/windows/build_windows.dart
@@ -14,10 +14,12 @@
 import 'msbuild_utils.dart';
 
 /// Builds the Windows project using msbuild.
-Future<void> buildWindows(WindowsProject windowsProject, BuildInfo buildInfo) async {
+Future<void> buildWindows(WindowsProject windowsProject, BuildInfo buildInfo, {String target = 'lib/main.dart'}) async {
   final Map<String, String> environment = <String, String>{
     'FLUTTER_ROOT': Cache.flutterRoot,
-    'EXTRA_BUNDLE_FLAGS': buildInfo?.trackWidgetCreation == true ? '--track-widget-creation' : '',
+    'FLUTTER_TARGET': target,
+    'PROJECT_DIR': windowsProject.project.directory.path,
+    'TRACK_WIDGET_CREATION': (buildInfo?.trackWidgetCreation == true).toString(),
   };
   writePropertySheet(windowsProject.generatedPropertySheetFile, environment);