11using System ;
2+ using System . Collections . Generic ;
23using System . Collections . ObjectModel ;
34using System . Diagnostics ;
45using System . IO ;
@@ -99,7 +100,7 @@ private void ResetAction()
99100 ConfigModel . DriverDirectory = string . Empty ;
100101 ConfigModel . ReportUrl = string . Empty ;
101102 ConfigModel . UpdateUrl = string . Empty ;
102- ConfigModel . AppName = string . Empty ;
103+ ConfigModel . AppName = "Update" ;
103104 ConfigModel . MainAppName = string . Empty ;
104105 ConfigModel . ClientVersion = string . Empty ;
105106 ConfigModel . Encoding = Encodings . First ( ) ;
@@ -174,9 +175,7 @@ await DifferentialCore.Instance.Clean(ConfigModel.AppDirectory,
174175 }
175176 catch ( Exception ex )
176177 {
177- Trace . WriteLine ( $ "Failed to copy driver files: { ex . Message } ") ;
178178 await MessageBox . ShowAsync ( "Failed to copy driver files. Please check the driver directory permissions and available disk space." , "Warning" , Buttons . OK ) ;
179- // Continue with the build process even if driver copying fails
180179 }
181180 }
182181
@@ -190,7 +189,7 @@ await DifferentialCore.Instance.Clean(ConfigModel.AppDirectory,
190189
191190 CompressProvider . Compress ( operationType
192191 , ConfigModel . PatchDirectory
193- , Path . Combine ( parentDirectory , ConfigModel . Name + ConfigModel . Format . Value )
192+ , Path . Combine ( parentDirectory , ConfigModel . Name + ConfigModel . Format . Value )
194193 , false , encoding ) ;
195194
196195 if ( Directory . Exists ( ConfigModel . PatchDirectory ) )
@@ -209,7 +208,6 @@ await DifferentialCore.Instance.Clean(ConfigModel.AppDirectory,
209208 }
210209 catch ( Exception e )
211210 {
212- Trace . WriteLine ( e . Message ) ;
213211 await MessageBox . ShowAsync ( e . Message , "Fail" , Buttons . OK ) ;
214212 }
215213 }
@@ -318,11 +316,18 @@ private void ReadProjectConfiguration()
318316
319317 // Read ClientVersion
320318 ConfigModel . ClientVersion = CsprojReader . ReadClientVersion ( ConfigModel . ReleaseDirectory ) ;
321-
322- // Set AppName to MainAppName if MainAppName is not empty
323- if ( ! string . IsNullOrEmpty ( ConfigModel . MainAppName ) )
319+
320+ // Read ReleaseDirectory
321+ var directory = SearchExeFileAndGetDirectory ( ConfigModel . ReleaseDirectory , ConfigModel . MainAppName ) ;
322+ var outputPath = CsprojReader . ReadOutputPath ( ConfigModel . ReleaseDirectory ) ;
323+
324+ if ( ! string . IsNullOrWhiteSpace ( outputPath ) )
325+ {
326+ ConfigModel . ReleaseDirectory = outputPath ;
327+ }
328+ else if ( ! string . IsNullOrWhiteSpace ( directory ) )
324329 {
325- ConfigModel . AppName = ConfigModel . MainAppName ;
330+ ConfigModel . ReleaseDirectory = SearchExeFileAndGetDirectory ( ConfigModel . ReleaseDirectory , ConfigModel . MainAppName ) ;
326331 }
327332 }
328333 catch ( Exception ex )
@@ -360,4 +365,116 @@ private async Task<string> CreateConfigInfoFile()
360365 throw ;
361366 }
362367 }
368+
369+ /// <summary>
370+ /// Searches for the specified exe file in release/debug directories under bin directories
371+ /// in the specified root directory, and returns the directories of the found exe files as a concatenated string
372+ /// </summary>
373+ /// <param name="rootDirectory">Root directory path</param>
374+ /// <param name="exeFileName">Name of the exe file to search (including extension)</param>
375+ /// <returns>Paths of directories containing matching exe files, separated by semicolons;
376+ /// returns empty string if no files are found</returns>
377+ /// <exception cref="ArgumentNullException">Thrown when parameter is null or whitespace</exception>
378+ /// <exception cref="ArgumentException">Thrown when parameter format is invalid</exception>
379+ /// <exception cref="DirectoryNotFoundException">Thrown when root directory does not exist</exception>
380+ private static string SearchExeFileAndGetDirectory ( string rootDirectory , string exeFileName )
381+ {
382+ // Temporarily store directories of found exe files
383+ List < string > exeDirectories = new List < string > ( ) ;
384+
385+ // ===================== Step 1: Comprehensive parameter validation =====================
386+ // 1. Validate if rootDirectory is null, empty or whitespace
387+ if ( string . IsNullOrWhiteSpace ( rootDirectory ) )
388+ {
389+ throw new ArgumentNullException ( nameof ( rootDirectory ) , "Root directory path cannot be null, empty or whitespace" ) ;
390+ }
391+
392+ // 2. Validate if rootDirectory path format is legal (avoid invalid paths like "::/\\abc")
393+ try
394+ {
395+ // Attempt to resolve the path, exception will be thrown if format is illegal
396+ string fullPath = Path . GetFullPath ( rootDirectory ) ;
397+ }
398+ catch ( Exception ex )
399+ {
400+ throw new ArgumentException ( $ "Invalid root directory path format: { ex . Message } ", nameof ( rootDirectory ) , ex ) ;
401+ }
402+
403+ // 3. Validate if exeFileName is null, empty or whitespace
404+ if ( string . IsNullOrWhiteSpace ( exeFileName ) )
405+ {
406+ throw new ArgumentNullException ( nameof ( exeFileName ) , "Exe file name to search cannot be null, empty or whitespace" ) ;
407+ }
408+
409+ // 6. Basic validation: Check if root directory exists (kept after format validation)
410+ if ( ! Directory . Exists ( rootDirectory ) )
411+ {
412+ throw new DirectoryNotFoundException ( $ "Specified root directory does not exist: { rootDirectory } ") ;
413+ }
414+
415+ // ===================== Step 2: Original core search logic =====================
416+ try
417+ {
418+ // 1. Recursively find all bin directories (case-insensitive)
419+ var binDirectories = Directory . EnumerateDirectories (
420+ rootDirectory ,
421+ "bin" ,
422+ SearchOption . AllDirectories )
423+ . Where ( dir => string . Equals ( Path . GetFileName ( dir ) , "bin" , StringComparison . OrdinalIgnoreCase ) ) ;
424+
425+ foreach ( string binDir in binDirectories )
426+ {
427+ string targetDir = null ;
428+
429+ // 2. Prioritize checking release directory
430+ string releaseDir = Path . Combine ( binDir , "release" ) ;
431+ if ( Directory . Exists ( releaseDir ) )
432+ {
433+ targetDir = releaseDir ;
434+ }
435+ else
436+ {
437+ // Fallback to check debug directory
438+ string debugDir = Path . Combine ( binDir , "debug" ) ;
439+ if ( Directory . Exists ( debugDir ) )
440+ {
441+ targetDir = debugDir ;
442+ }
443+ }
444+
445+ // 3. If release/debug directory is found, search for exe files
446+ if ( ! string . IsNullOrEmpty ( targetDir ) )
447+ {
448+ var exeFiles = Directory . EnumerateFiles (
449+ targetDir ,
450+ "*.exe" ,
451+ SearchOption . AllDirectories ) ;
452+
453+ foreach ( string filePath in exeFiles )
454+ {
455+ string fileName = Path . GetFileName ( filePath ) ;
456+ if ( fileName . Contains ( exeFileName ) )
457+ {
458+ string exeDir = Path . GetDirectoryName ( filePath ) ;
459+ if ( ! exeDirectories . Contains ( exeDir ) )
460+ {
461+ exeDirectories . Add ( exeDir ) ;
462+ }
463+ }
464+ }
465+ }
466+ }
467+ }
468+ catch ( UnauthorizedAccessException ex )
469+ {
470+ Console . WriteLine ( $ "Insufficient permissions to access directory: { ex . Message } ") ;
471+ }
472+ catch ( PathTooLongException ex )
473+ {
474+ Console . WriteLine ( $ "File path is too long: { ex . Message } ") ;
475+ }
476+
477+ // Concatenate directories into a string and return
478+ return string . Join ( ";" , exeDirectories ) ;
479+ }
363480}
0 commit comments