@@ -151,6 +151,84 @@ public void DotNetRunWaitForExit ()
151151 }
152152
153153 [ Test ]
154+ public void DotNetRunWithDeviceParameter ( )
155+ {
156+ const string logcatMessage = "DOTNET_RUN_DEVICE_TEST_67890" ;
157+ var proj = new XamarinAndroidApplicationProject ( ) ;
158+
159+ // Enable verbose output from Microsoft.Android.Run for debugging
160+ proj . SetProperty ( "_AndroidRunExtraArgs" , "--verbose" ) ;
161+
162+ // Add a Console.WriteLine that will appear in logcat
163+ proj . MainActivity = proj . DefaultMainActivity . Replace (
164+ "//${AFTER_ONCREATE}" ,
165+ $ "Console.WriteLine (\" { logcatMessage } \" );") ;
166+
167+ using var builder = CreateApkBuilder ( ) ;
168+ builder . Save ( proj ) ;
169+
170+ var dotnet = new DotNetCLI ( Path . Combine ( Root , builder . ProjectDirectory , proj . ProjectFilePath ) ) ;
171+ Assert . IsTrue ( dotnet . Build ( ) , "`dotnet build` should succeed" ) ;
172+
173+ // Get the attached device serial
174+ var serial = GetAttachedDeviceSerial ( ) ;
175+
176+ // Start dotnet run with Device parameter, which should set $(AdbTarget)
177+ using var process = dotnet . StartRun ( waitForExit : true , parameters : [ $ "Device={ serial } "] ) ;
178+
179+ var locker = new Lock ( ) ;
180+ var output = new StringBuilder ( ) ;
181+ var outputReceived = new ManualResetEventSlim ( false ) ;
182+ bool foundMessage = false ;
183+ bool foundAdbTarget = false ;
184+
185+ process . OutputDataReceived += ( sender , e ) => {
186+ if ( e . Data != null ) {
187+ lock ( locker ) {
188+ output . AppendLine ( e . Data ) ;
189+ // Check for the --adb-target argument in verbose output
190+ if ( e . Data . Contains ( $ "Target: -s { serial } ") ) {
191+ foundAdbTarget = true ;
192+ }
193+ if ( e . Data . Contains ( logcatMessage ) ) {
194+ foundMessage = true ;
195+ outputReceived . Set ( ) ;
196+ }
197+ }
198+ }
199+ } ;
200+ process . ErrorDataReceived += ( sender , e ) => {
201+ if ( e . Data != null ) {
202+ lock ( locker ) {
203+ output . AppendLine ( $ "STDERR: { e . Data } ") ;
204+ }
205+ }
206+ } ;
207+
208+ process . BeginOutputReadLine ( ) ;
209+ process . BeginErrorReadLine ( ) ;
210+
211+ // Wait for the expected message or timeout
212+ bool messageFound = outputReceived . Wait ( TimeSpan . FromSeconds ( 60 ) ) ;
213+
214+ // Kill the process (simulating Ctrl+C)
215+ if ( ! process . HasExited ) {
216+ process . Kill ( entireProcessTree : true ) ;
217+ process . WaitForExit ( ) ;
218+ }
219+
220+ // Write the output to a log file for debugging
221+ string logPath = Path . Combine ( Root , builder . ProjectDirectory , "dotnet-run-device-output.log" ) ;
222+ File . WriteAllText ( logPath , output . ToString ( ) ) ;
223+ TestContext . AddTestAttachment ( logPath ) ;
224+
225+ Assert . IsTrue ( foundAdbTarget , $ "Expected --adb-target argument with serial '{ serial } ' was not found in verbose output. See { logPath } for details.") ;
226+ Assert . IsTrue ( foundMessage , $ "Expected message '{ logcatMessage } ' was not found in output. See { logPath } for details.") ;
227+ }
228+
229+ [ Test ]
230+ [ TestCase ( true ) ]
231+ [ TestCase ( false ) ]
154232 public void DeployToDevice ( [ Values ] bool isRelease , [ Values ] AndroidRuntime runtime )
155233 {
156234 if ( IgnoreUnsupportedConfiguration ( runtime , release : isRelease ) ) {
0 commit comments