Build the solution on Windows (#33528)

Switch from building Runner.vcxproj to Runner.sln on Windows, to allow
for multiple-project builds (e.g., separate plugin projects).
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart
index 4433c30..60c8f12 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -615,6 +615,9 @@
   // The MSBuild project file.
   File get vcprojFile => _editableDirectory.childFile('Runner.vcxproj');
 
+  // The MSBuild solution file.
+  File get solutionFile => _editableDirectory.childFile('Runner.sln');
+
   /// 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.
diff --git a/packages/flutter_tools/lib/src/windows/build_windows.dart b/packages/flutter_tools/lib/src/windows/build_windows.dart
index c31708b..eddd533 100644
--- a/packages/flutter_tools/lib/src/windows/build_windows.dart
+++ b/packages/flutter_tools/lib/src/windows/build_windows.dart
@@ -38,16 +38,16 @@
   );
 
   final String configuration = buildInfo.isDebug ? 'Debug' : 'Release';
-  final String projectPath = windowsProject.vcprojFile.path;
+  final String solutionPath = windowsProject.solutionFile.path;
   // Run the script with a relative path to the project using the enclosing
   // directory as the workingDirectory, to avoid hitting the limit on command
   // lengths in batch scripts if the absolute path to the project is long.
   final Process process = await processManager.start(<String>[
     buildScript,
     vcvarsScript,
-    fs.path.basename(projectPath),
+    fs.path.basename(solutionPath),
     configuration,
-  ], workingDirectory: fs.path.dirname(projectPath));
+  ], workingDirectory: fs.path.dirname(solutionPath));
   final Status status = logger.startProgress(
     'Building Windows application...',
     timeout: null,
diff --git a/packages/flutter_tools/test/commands/build_windows_test.dart b/packages/flutter_tools/test/commands/build_windows_test.dart
index 1fde6dc..6f9d98d 100644
--- a/packages/flutter_tools/test/commands/build_windows_test.dart
+++ b/packages/flutter_tools/test/commands/build_windows_test.dart
@@ -25,7 +25,7 @@
   final MockPlatform windowsPlatform = MockPlatform()
       ..environment['PROGRAMFILES(X86)'] = r'C:\Program Files (x86)\';
   final MockPlatform notWindowsPlatform = MockPlatform();
-  const String projectPath = r'C:\windows\Runner.vcxproj';
+  const String solutionPath = r'C:\windows\Runner.sln';
   const String visualStudioPath = r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community';
   const String vcvarsPath = visualStudioPath + r'\VC\Auxiliary\Build\vcvars64.bat';
 
@@ -63,7 +63,7 @@
   testUsingContext('Windows build fails when there is no vcvars64.bat', () async {
     final BuildCommand command = BuildCommand();
     applyMocksToCommand(command);
-    fs.file(projectPath).createSync(recursive: true);
+    fs.file(solutionPath).createSync(recursive: true);
     expect(createTestCommandRunner(command).run(
       const <String>['build', 'windows']
     ), throwsA(isInstanceOf<ToolExit>()));
@@ -87,7 +87,7 @@
   testUsingContext('Windows build fails on non windows platform', () async {
     final BuildCommand command = BuildCommand();
     applyMocksToCommand(command);
-    fs.file(projectPath).createSync(recursive: true);
+    fs.file(solutionPath).createSync(recursive: true);
     enableVcvarsMocking();
     fs.file('pubspec.yaml').createSync();
     fs.file('.packages').createSync();
@@ -103,7 +103,7 @@
   testUsingContext('Windows build invokes msbuild and writes generated files', () async {
     final BuildCommand command = BuildCommand();
     applyMocksToCommand(command);
-    fs.file(projectPath).createSync(recursive: true);
+    fs.file(solutionPath).createSync(recursive: true);
     enableVcvarsMocking();
     fs.file('pubspec.yaml').createSync();
     fs.file('.packages').createSync();
@@ -111,9 +111,9 @@
     when(mockProcessManager.start(<String>[
       r'C:\packages\flutter_tools\bin\vs_build.bat',
       vcvarsPath,
-      fs.path.basename(projectPath),
+      fs.path.basename(solutionPath),
       'Release',
-    ], workingDirectory: fs.path.dirname(projectPath))).thenAnswer((Invocation invocation) async {
+    ], workingDirectory: fs.path.dirname(solutionPath))).thenAnswer((Invocation invocation) async {
       return mockProcess;
     });