Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows implementation of which command is not properly stripping \r characters from newlines #1611

Closed
con-9 opened this issue Jan 3, 2024 · 20 comments · Fixed by #1628
Closed
Assignees
Labels
bug Something isn't working

Comments

@con-9
Copy link

con-9 commented Jan 3, 2024

1
2

@con-9 con-9 added the bug Something isn't working label Jan 3, 2024
@con-9 con-9 changed the title fix: Run shorebird release android --artifact apk error on Windows10 Run shorebird release android --artifact apk error on Windows10 Jan 3, 2024
@con-9
Copy link
Author

con-9 commented Jan 3, 2024

It will report " OS Error: The syntax of the filename, directory name, or volume label is incorrect. c links, path = 'D:\platform-tools\adb.exe, errno = 123" while runing the step "Detecting release version" and my location of adb is correct. Waiting for help,Thank you.

@Duskfen
Copy link

Duskfen commented Jan 3, 2024

Does this also happen when you run/build it "normally" with flutter?
If so, have a look here: flutter/flutter#99954 (comment)

@con-9
Copy link
Author

con-9 commented Jan 3, 2024

Does this also happen when you run/build it "normally" with flutter? If so, have a look here: flutter/flutter#99954 (comment)

i can correctly run the command "flutter run" or "flutter build apk",so it not work for me

@bryanoltman
Copy link
Contributor

I tried moving my ADB to a different drive (D:\adb.exe) and was able to successfully create an Android release, so I don't think that's the problem (or at least not the entire problem).

@con-9 can you run shorebird doctor -v? That might tell us something helpful.

@bryanoltman
Copy link
Contributor

I also tried replacing adb.exe in my Android sdk's platform tools with a symlink to adb.exe on a different drive and was able to successfully create a release that was as well. I'll wait to hear back what the results of shorebird doctor -v are. If you could also run the shorebird release android command with the -v flag and share the output (ideally as pasted text instead of a screenshot) that would be useful too.

@bryanoltman bryanoltman moved this to Pending Customer Reply in iOS Beta Jan 3, 2024
@con-9
Copy link
Author

con-9 commented Jan 4, 2024

I also tried replacing adb.exe in my Android sdk's platform tools with a symlink to adb.exe on a different drive and was able to successfully create a release that was as well. I'll wait to hear back what the results of shorebird doctor -v are. If you could also run the shorebird release android command with the -v flag and share the output (ideally as pasted text instead of a screenshot) that would be useful too.

Here's the result of running the command "shorebird doctor -v":

Unhandled exception:
' (OS Error: 文件名、目录名或卷标语法不正确。links, path = 'D:\Android\Sdk\platform-tools\adb.exe
, errno = 123)
#0 FileSystemEntity._throwIfError (dart:io/file_system_entity.dart:839:7)
#1 FileSystemEntity.resolveSymbolicLinksSync (dart:io/file_system_entity.dart:358:5)
#2 AndroidSdk._androidSdkPathFromAdb (package:shorebird_cli/src/android_sdk.dart:95:48)
#3 AndroidSdk.path (package:shorebird_cli/src/android_sdk.dart:42:31)
#4 DoctorCommand.run (package:shorebird_cli/src/commands/doctor_command.dart:64:31)

#5 CommandRunner.runCommand (package:args/command_runner.dart:212:13)

#6 ShorebirdCliCommandRunner.runCommand (package:shorebird_cli/src/command_runner.dart:183:18)

#7 ShorebirdCliCommandRunner.run (package:shorebird_cli/src/command_runner.dart:99:14)

#8 main (file:///C:/Users/ws/.shorebird/packages/shorebird_cli/bin/shorebird.dart:27:5)

@bryanoltman bryanoltman moved this from Pending Customer Reply to Customers in iOS Beta Jan 4, 2024
@bryanoltman
Copy link
Contributor

It looks like this error is coming from Windows (see here), but it surprises me that flutter commands would work if the path to adb were invalid. What shell are you using (e.g., powershell, cmd.exe, git bash)? If powershell or cmd.exe, can you try executing D:\Android\Sdk\platform-tools\adb.exe? You should see the usage prompt (starting with Android Debug Bridge version x.y.z)

@bryanoltman bryanoltman moved this from Customers to Pending Customer Reply in iOS Beta Jan 4, 2024
@con-9
Copy link
Author

con-9 commented Jan 5, 2024

D:\Android\Sdk\platform-tools\adb.exe

Im using WindowsPowershell in AndroidStudio,and i think i dont have any special characters in my adb path

here is my powershell path
1

2

@bryanoltman
Copy link
Contributor

This all looks right. Hmm, this is strange. Let me think for a bit and I'll see if I can come up with a good idea of how to pinpoint what's going on here. Our first step is probably to try to come reproduce this, ideally in a much smaller codebase (i.e., a single dart script).

@bryanoltman bryanoltman moved this from Pending Customer Reply to Customers in iOS Beta Jan 5, 2024
@bryanoltman bryanoltman changed the title Run shorebird release android --artifact apk error on Windows10 OS Error: The syntax of the filename, directory name, or volume label is incorrect" Jan 5, 2024
@bryanoltman bryanoltman changed the title OS Error: The syntax of the filename, directory name, or volume label is incorrect" Windows 10 error when locating ABB: "OS Error: The syntax of the filename, directory name, or volume label is incorrect" Jan 5, 2024
@bryanoltman bryanoltman changed the title Windows 10 error when locating ABB: "OS Error: The syntax of the filename, directory name, or volume label is incorrect" Windows 10 error when locating ADB: "OS Error: The syntax of the filename, directory name, or volume label is incorrect" Jan 5, 2024
@bryanoltman
Copy link
Contributor

bryanoltman commented Jan 5, 2024

Ok, here is a dart script that I think should reproduce the issue. If you could run this and let me know what you see, that would be really helpful.

The script:

import 'dart:io';

void main() {
  checkEnvVar('ANDROID_HOME');
  checkEnvVar('ANDROID_SDK_ROOT');
  checkEnvVar('USERPROFILE');

  final userprofile = Platform.environment['USERPROFILE'];
  if (userprofile != null) {
    final userProfileSdkPath = '$userprofile\\AppData\\Local\\Android\\Sdk';
    print('USERPROFILE sdk path: $userProfileSdkPath');
    print(
      'USERPROFILE sdk path is valid: ${isValidSdkPath(userProfileSdkPath)}',
    );
    final adbExecutable = checkForAdbExecutable(userProfileSdkPath);
    if (adbExecutable != null) {
      print('running adb');
      final result = Process.runSync(adbExecutable.path, []);
      print('adb output:');
      print(result.stdout);
    }
  }
}

File? checkForAdbExecutable(String sdkPath) {
  final adbPath = '$sdkPath\\platform-tools\\adb.exe';
  print('checking for adb at: $adbPath');
  final adbFile = File(adbPath);
  print('adbFile: $adbFile');
  if (adbFile.existsSync()) {
    print('adbFile exists');
    return adbFile;
  } else {
    print('adbFile does not exist');
    return null;
  }
}

bool isValidSdkPath(String path) {
  final directory = Directory(path);
  final licensesDirectory = Directory('$path\\licenses');
  final platformToolsDirectory = Directory('$path\\platform-tools');
  return directory.existsSync() &&
      (licensesDirectory.existsSync() || platformToolsDirectory.existsSync());
}

void checkEnvVar(String envVarName) {
  final value = Platform.environment[envVarName];
  print('$envVarName: $value');
  if (value != null) {
    final directory = Directory(value);
    print('$envVarName directory: $directory');
  }
}

What I see:

ANDROID_HOME: null
ANDROID_SDK_ROOT: null
USERPROFILE: C:\Users\bryan
USERPROFILE directory: Directory: 'C:\Users\bryan'
ANDROID_SDK_ROOT: null
USERPROFILE: C:\Users\bryan
USERPROFILE directory: Directory: 'C:\Users\bryan'
USERPROFILE sdk path: C:\Users\bryan\AppData\Local\Android\Sdk
USERPROFILE sdk path is valid: true
checking for adb at: C:\Users\bryan\AppData\Local\Android\Sdk\platform-tools\adb.exe
adbFile: File: 'C:\Users\bryan\AppData\Local\Android\Sdk\platform-tools\adb.exe'
adbFile exists
running adb
adb output:
Android Debug Bridge version 1.0.41

Version 34.0.5-10900879

Installed as C:\Users\bryan\AppData\Local\Android\Sdk\platform-tools\adb.exe

Running on Windows 10.0.19045
...

@con-9
Copy link
Author

con-9 commented Jan 8, 2024

Sorry for the late reply

i have been customed my sdk path like this:

image

so i modified your code a bit to use my local sdk path, and that's what i see

D:/fvm/default/bin/cache/dart-sdk/bin/dart.exe --enable-asserts D:\AllProject\AndroidStudioProject\flutter\shore_bird_test_app\lib\main.dart
ANDROID_HOME: null
ANDROID_SDK_ROOT: null
USERPROFILE: C:\Users\ws
USERPROFILE directory: Directory: 'C:\Users\ws'
USERPROFILE sdk path: D:\Android\Sdk
USERPROFILE sdk path is valid: true
checking for adb at: D:\Android\Sdk\platform-tools\adb.exe
adbFile: File: 'D:\Android\Sdk\platform-tools\adb.exe'
adbFile exists
running adb
adb output:
Android Debug Bridge version 1.0.41
Version 34.0.4-10411341
Installed as D:\Android\Sdk\platform-tools\adb.exe
Running on Windows 10.0.19045
....

and that's what i see without change your code:

ANDROID_HOME: null
ANDROID_SDK_ROOT: null
USERPROFILE: C:\Users\ws
USERPROFILE directory: Directory: 'C:\Users\ws'
USERPROFILE sdk path: C:\Users\ws\AppData\Local\Android\Sdk
USERPROFILE sdk path is valid: false
checking for adb at: C:\Users\ws\AppData\Local\Android\Sdk\platform-tools\adb.exe
adbFile: File: 'C:\Users\ws\AppData\Local\Android\Sdk\platform-tools\adb.exe'
adbFile does not exist

Process finished with exit code 0

@con-9
Copy link
Author

con-9 commented Jan 8, 2024

is it detects the defalut adb path of the C drive in shorebird?

@bryanoltman
Copy link
Contributor

so i modified your code a bit to use my local sdk path, and that's what i see

Can you share you modifications?

@con-9
Copy link
Author

con-9 commented Jan 8, 2024

so i modified your code a bit to use my local sdk path, and that's what i see

Can you share you modifications?

I just custom the sdk path in line 10,because there nothing in C:\Users\myuserName\AppData\Local\Android

void main() {
  checkEnvVar('ANDROID_HOME');
  checkEnvVar('ANDROID_SDK_ROOT');
  checkEnvVar('USERPROFILE');

  final userprofile = Platform.environment['USERPROFILE'];
  if (userprofile != null) {
    const userProfileSdkPath = 'D:\\Android\\Sdk';   //modification
    print('USERPROFILE sdk path: $userProfileSdkPath');
    print(
      'USERPROFILE sdk path is valid: ${isValidSdkPath(userProfileSdkPath)}',
    );
    final adbExecutable = checkForAdbExecutable(userProfileSdkPath);
    if (adbExecutable != null) {
      print('running adb');
      final result = Process.runSync(adbExecutable.path, []);
      print('adb output:');
      print(result.stdout);
    }
  }
}

@con-9
Copy link
Author

con-9 commented Jan 8, 2024

since i migrate my android sdk location, i deleted the file in "C:\Users\myuserName\AppData\Local\Android" to reduce the C drive size

@bryanoltman
Copy link
Contributor

Gotch. This code snippet was meant to extract the relevant bits of shorebird's ADB lookup into a place where we could more easily pinpoint the issue. It's good to see that hardcoding D:\\Android\\Sdk works, and I'd like to see if we can replicate how shorebird finds the Android SDK and reproduce the issue. It looks like none of the places being checked in this script are finding adb. I've updated the script to check every place we might look, if you wouldn't mind running this.

import 'dart:io';

void main() {
  checkEnvVar('ANDROID_HOME');
  checkEnvVar('ANDROID_SDK_ROOT');
  checkEnvVar('USERPROFILE');

  final userprofile = Platform.environment['USERPROFILE'];
  if (userprofile != null) {
    final userProfileSdkPath = '$userprofile\\AppData\\Local\\Android\\Sdk';
    print('USERPROFILE sdk path: $userProfileSdkPath');
    print(
      'USERPROFILE sdk path is valid: ${isValidSdkPath(userProfileSdkPath)}',
    );
    final adbExecutable = checkForAdbExecutable(userProfileSdkPath);
    if (adbExecutable != null) {
      print('running adb');
      final result = Process.runSync(adbExecutable.path, []);
      print('adb output:');
      print(result.stdout);
    }
  }

  final sdkPathFromAapt = _androidSdkPathFromAapt();
  print('sdkPathFromAapt: $sdkPathFromAapt');
  if (sdkPathFromAapt != null) {
    print('sdkPathFromAapt is valid: ${isValidSdkPath(sdkPathFromAapt)}');
    final adbExecutable = checkForAdbExecutable(sdkPathFromAapt);
    if (adbExecutable != null) {
      print('running adb');
      final result = Process.runSync(adbExecutable.path, []);
      print('adb output:');
      print(result.stdout);
    }
  }

  final sdkPathFromAdb = _androidSdkPathFromAdb();
  print('sdkPathFromAdb: $sdkPathFromAdb');
  if (sdkPathFromAdb != null) {
    print('sdkPathFromAdb is valid: ${isValidSdkPath(sdkPathFromAdb)}');
    final adbExecutable = checkForAdbExecutable(sdkPathFromAdb);
    if (adbExecutable != null) {
      print('running adb');
      final result = Process.runSync(adbExecutable.path, []);
      print('adb output:');
      print(result.stdout);
    }
  }
}

File? checkForAdbExecutable(String sdkPath) {
  final adbPath = '$sdkPath\\platform-tools\\adb.exe';
  print('checking for adb at: $adbPath');
  final adbFile = File(adbPath);
  print('adbFile: $adbFile');
  if (adbFile.existsSync()) {
    print('adbFile exists');
    return adbFile;
  } else {
    print('adbFile does not exist');
    return null;
  }
}

String? _androidSdkPathFromAapt() {
  print('checking for aapt');
  final maybeAaptPath = which('aapt');
  print('maybeAaptPath: $maybeAaptPath');
  if (maybeAaptPath == null) {
    return null;
  }

  // Resolve path to aapt if it is a symlink.
  final resolvedAaptPath = File(maybeAaptPath).resolveSymbolicLinksSync();
  return File(resolvedAaptPath).parent.parent.parent.path;
}

String? _androidSdkPathFromAdb() {
  print('checking for adb');
  final maybeAdbPath = which('adb');
  print('maybeAdbPath: $maybeAdbPath');
  if (maybeAdbPath == null) {
    return null;
  }

  // Resolve path to adb if it is a symlink.
  final resolvedAdbPath = File(maybeAdbPath).resolveSymbolicLinksSync();
  return File(resolvedAdbPath).parent.parent.path;
}

String? which(String executableName) {
  final result = Process.runSync('where.exe', [executableName]);
  if (result.exitCode != 0) {
    return null;
  }

  // By default, where.exe will list all matching executables on PATH. We want
  // to return the first one.
  return (result.stdout as String).split('\n').firstOrNull;
}

bool isValidSdkPath(String path) {
  final directory = Directory(path);
  final licensesDirectory = Directory('$path\\licenses');
  final platformToolsDirectory = Directory('$path\\platform-tools');
  return directory.existsSync() &&
      (licensesDirectory.existsSync() || platformToolsDirectory.existsSync());
}

void checkEnvVar(String envVarName) {
  final value = Platform.environment[envVarName];
  print('$envVarName: $value');
  if (value != null) {
    final directory = Directory(value);
    print('$envVarName directory: $directory');
  }
}

@con-9
Copy link
Author

con-9 commented Jan 9, 2024

That's what i see with your latest code:

ANDROID_HOME: null
ANDROID_SDK_ROOT: null
USERPROFILE: C:\Users\ws
USERPROFILE directory: Directory: 'C:\Users\ws'
USERPROFILE sdk path: C:\Users\ws\AppData\Local\Android\Sdk
USERPROFILE sdk path is valid: false
checking for adb at: C:\Users\ws\AppData\Local\Android\Sdk\platform-tools\adb.exe
adbFile: File: 'C:\Users\ws\AppData\Local\Android\Sdk\platform-tools\adb.exe'
adbFile does not exist
checking for aapt
maybeAaptPath: null
sdkPathFromAapt: null
checking for adb
maybeAdbPath: D:\Android\Sdk\platform-tools\adb.exe
Unhandled exception:
' (OS Error: 文件名、目录名或卷标语法不正确。
, errno = 123)
#0      FileSystemEntity._throwIfError (dart:io/file_system_entity.dart:839:7)
#1      FileSystemEntity.resolveSymbolicLinksSync (dart:io/file_system_entity.dart:358:5)
#2      _androidSdkPathFromAdb (package:shorebird_test/test.dart:87:46)
#3      main (package:shorebird_test/test.dart:37:26)
#4      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:296:19)
#5      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)

Process finished with exit code 255

it report error in this method:
image

when we use the command "where.exe" to find the path of adb,it will return a path end with "\r",so the code went wrong
image

@con-9
Copy link
Author

con-9 commented Jan 9, 2024

A less rigorous approach is replace the carriage return with an empty string like this(the method _androidSdkPathFromAapt will have the same problem):

String? _androidSdkPathFromAdb() {
  print('checking for adb');
  String? maybeAdbPath = which('adb');
  print('maybeAdbPath: $maybeAdbPath');
  if (maybeAdbPath == null) {
    return null;
  } else {
    maybeAdbPath = maybeAdbPath.replaceAll("\r", "");
  }

  // Resolve path to adb if it is a symlink.
  final resolvedAdbPath = File(maybeAdbPath).resolveSymbolicLinksSync();
  return File(resolvedAdbPath).parent.parent.path;
}

then it will correctly run:

ANDROID_HOME: null
ANDROID_SDK_ROOT: null
USERPROFILE: C:\Users\ws
USERPROFILE directory: Directory: 'C:\Users\ws'
USERPROFILE sdk path: C:\Users\ws\AppData\Local\Android\Sdk
USERPROFILE sdk path is valid: false
checking for adb at: C:\Users\ws\AppData\Local\Android\Sdk\platform-tools\adb.exe
adbFile: File: 'C:\Users\ws\AppData\Local\Android\Sdk\platform-tools\adb.exe'
adbFile does not exist
checking for aapt
maybeAaptPath: null
sdkPathFromAapt: null
checking for adb
maybeAdbPath: D:\Android\Sdk\platform-tools\adb.exe
sdkPathFromAdb: D:\Android\Sdk
sdkPathFromAdb is valid: true
checking for adb at: D:\Android\Sdk\platform-tools\adb.exe
adbFile: File: 'D:\Android\Sdk\platform-tools\adb.exe'
adbFile exists
running adb
adb output:
Android Debug Bridge version 1.0.41
Version 34.0.4-10411341
Installed as D:\Android\Sdk\platform-tools\adb.exe
Running on Windows 10.0.19045

maybe there's a better way

@gauravmehta13
Copy link

gauravmehta13 commented Jan 9, 2024

@con-9 Can you try setting your ANDROID_HOME to the correct path?

@con-9
Copy link
Author

con-9 commented Jan 9, 2024

@con-9 Can you try setting your ANDROID_HOME to the correct path?

It is work for me

However, it would be better to fix the method of getting the adb path, as not everyone will configure the environment exactly as expected

@bryanoltman bryanoltman changed the title Windows 10 error when locating ADB: "OS Error: The syntax of the filename, directory name, or volume label is incorrect" Windows implementation of which command is not properly stripping \r characters from newlines Jan 12, 2024
@github-project-automation github-project-automation bot moved this from Customers to Done in iOS Beta Jan 12, 2024
@felangel felangel self-assigned this Jan 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
No open projects
Status: Done
Development

Successfully merging a pull request may close this issue.

5 participants