dotnet / dotnet/macios

`dotnet build -f net9.0-ios` fails if `mlaunch` path has spaces

Open
#22,481 5 comments 0 reactions 0 assignees View on GitHub
bug mlaunch
Dominant language
C#
Stars
2.9k
Forks
576
Avg merge
2d 17h
Merged PRs (30d)
108

Description

### Apple platform

iOS

### Framework version

net9.0-*

### Affected platform version

9.0.200

### Description

## Title
MSBuild fails to launch iOS simulator when mlaunch path contains spaces (error 127)

## Description
When using `dotnet build -t:Run -f net9.0-ios` to launch a .NET MAUI app in the iOS simulator, the command fails with error code 127 if the path to `mlaunch` contains spaces. This is due to MSBuild not properly escaping spaces in paths when creating temporary shell scripts.

The issue only occurs when using the combined build and run command. Running `mlaunch` directly with properly quoted paths works correctly.

## Environment
- macOS 24.3.0
- .NET SDK 9.0.200
- Xcode (latest version)
- .NET MAUI workload installed via `dotnet workload install maui`

## Investigation Results

Looking at the diagnostic output with `-v:diag`, we found that:

1. MSBuild creates a temporary shell script in `/var/folders/m_/v89b4sb95fz2lbt83sy2yjyh0000gn/T/MSBuildTempnat/`
2. The shell script fails because it doesn't properly handle spaces in the path:
```
/var/folders/m_/v89b4sb95fz2lbt83sy2yjyh0000gn/T/MSBuildTempnat/tmpf996f3bc7039479b8f6d69a939bafc4f.exec.cmd: line 2: /Users/nat/Library/Application: No such file or directory
```
3. This causes the shell script to exit with code 127 (command not found)
4. The named pipe between MSBuild processes breaks:
```
System.IO.IOException: Pipe is broken.
at System.IO.Pipes.NamedPipeServerStream.CheckConnectOperationsServer()
at System.IO.Pipes.NamedPipeServerStream.WaitForConnectionAsync(CancellationToken cancellationToken)
at Microsoft.Build.BackEnd.NodeEndpointOutOfProcBase.PacketPumpProc()
```
5. MSBuild reports the error 127 from the shell script

Further investigation reveals that the issue originates in `/Users/nat/Library/Application Support/dnvm/dn/packs/Microsoft.iOS.Sdk.net9.0_18.2/18.2.9180/targets/Xamarin.Shared.Sdk.targets`. The `MlaunchPath` property is defined but not properly escaped for shell execution:

```xml

$(_MlaunchPath)
$(_XamarinSdkRootDirectory)tools\bin\mlaunch

```

This property is later used in the `_InstallMobile` target to execute mlaunch:

```xml

```

When MSBuild generates the shell script from this Exec task, it doesn't properly escape the spaces in the path, leading to the shell interpreting "/Users/nat/Library/Application" as the command to execute.

## Expected Behavior
The command `dotnet build -t:Run -f net9.0-ios` should properly handle paths with spaces when creating temporary shell scripts, allowing the app to launch in the iOS simulator.

## Actual Behavior
The command fails with error 127 due to improper handling of spaces in paths.

## Additional Notes
- The issue is not with mlaunch itself, as it works when run directly with proper quoting
- The issue appears to be in how MSBuild creates and executes temporary shell scripts
- This affects any .NET MAUI iOS development where the SDK is installed in a path containing spaces

## Suggested Fix
MSBuild should properly escape paths containing spaces when creating temporary shell scripts for executing commands. This could be done by:
1. Properly quoting paths in the generated shell script
2. Using appropriate shell escaping for spaces and special characters
3. Or avoiding the creation of a shell script altogether and executing mlaunch directly

## Impact
This issue affects the developer experience for .NET MAUI iOS development, requiring developers to use a workaround instead of the documented approach. This is particularly impactful because:
1. The default installation paths on macOS often contain spaces
2. The error message (127) is not descriptive of the actual issue
3. The documented approach in the official documentation doesn't work in this common scenario

### Steps to Reproduce

## Steps to Reproduce

1. Create a new MAUI project:
```bash
dotnet new maui -n "MauiBlazorWeb"
cd MauiBlazorWeb
```

2. Try to build and run:
```bash
dotnet build -t:Run -f net9.0-ios
```

3. Observe error:
```
error MSB3073: The command "/Users/nat/Library/Application Support/dnvm/dn/packs/Microsoft.iOS.Sdk.net9.0_18.2/18.2.9180/tools/bin/mlaunch --launchsim bin/Debug/net9.0-ios/iossimulator-arm64/MauiBlazorWeb.app/ --device ":v2:runtime=com.apple.CoreSimulator.SimRuntime.iOS-18-2,devicetype=com.apple.CoreSimulator.SimDeviceType.iPad-mini-A17-Pro" --stdout /dev/ttys056 --stderr /dev/ttys056 --wait-for-exit:true" exited with code 127.
```

4. However, building separately works:
```bash
dotnet build -f net9.0-ios
```

5. And running mlaunch directly with proper quoting works:
```bash
'/Users/nat/Library/Application Support/dnvm/dn/packs/Microsoft.iOS.Sdk.net9.0_18.2/18.2.9180/tools/bin/mlaunch' --launchsim bin/Debug/net9.0-ios/iossimulator-arm64/MauiBlazorWeb.app/ --device ':v2:runtime=com.apple.CoreSimulator.SimRuntime.iOS-18-2,devicetype=com.apple.CoreSimulator.SimDeviceType.iPad-mini-A17-Pro' --stdout /dev/ttys056 --stderr /dev/ttys056 --wait-for-exit:true
```

### Did you find any workaround?

## Workaround
Split the process into two steps:
1. `dotnet build -f net9.0-ios`
2. Run mlaunch directly with proper path quoting

### Relevant logs

_No response_

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.