Issue
myapps.txt - contains the list of all packages found through adb shell pm list packages > myapps.txt
package:com.flipkart.android
package:com.android.certinstaller
package:com.android.carrierconfig
package:com.reddit.frontpage
package:com.wapi.wapicertmanage
package:com.brave.browser
Following is the code I wrote in the batch script to copy all the apps in one go from android to PC using ADB. Secondly, I'm splitting my string by colon(:) such that for example -
string1 contains package
and
string2 contains com.google.android.youtube
@echo off
setlocal enabledelayedexpansion
for /f "tokens=1* delims=:" %%i in (myapps.txt) do (
echo j: %%j
set string2=%%j
adb shell pm path !string2! > tmp.txt
set /p new=< tmp.txt
@echo on
@echo new: !new!
@echo off
set "str=%new%"
set "string1=%str::=" & set "string3=%"
del tmp.txt REM delete file after reading from it.
REM creating new folder for each app
mkdir apps_%input%\%string2%
REM pulling app from Android to PC
adb pull %string3% apps_%input%\%string2%
set /a count+=1
echo Done !count!
)
Here's the following output after 2 executions of for
loop I'm getting
j: com.flipkart.android
new: package:/data/app/com.flipkart.android-XOmoiAws7zOd07eM1nZIlg==/base.apk
A subdirectory or file apps_2\ already exists.
adb: error: failed to stat remote object 'apps_2\': No such file or directory
Done 1
j: com.android.certinstaller
new: package:/system/app/CertInstaller/CertInstaller.apk
A subdirectory or file apps_2\ already exists.
adb: error: failed to stat remote object 'apps_2\': No such file or directory
Done 2
Please help me why I'm getting this output. Also apps_2
don't exist before execution how it's prompting that it already exists.
But,the same thing is working perfectly in cmd prompt:
mkdir apps_2\com.flipkart.android
adb pull /data/app/com.flipkart.android-XOmoiAws7zOd07eM1nZIlg==/base.apk apps_2\com.flipkart.android
here's the output I received after execution
/data/app/com.flipkart.android-XOmoiAws7zOd07eM1nZIlg==/base.apk: 1 file pulled. 33.8 MB/s (12691794 bytes in 0.358s)
Solution
The batch file is not working as expected because of delayed expansion is used only for some, but not all environment variable references inside the FOR command block. Only the environment variable input
can be referenced with %input%
inside the command block as it is the only environment variable defined outside the command block and not modified inside the command block. All other environment variables are defined/modified inside the command block and referenced inside the command block. For that reason all environment variables except input
must be referenced with using !
instead of %
.
However, the usage of environment variables is not needed at all for this task.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
if not defined input set "input=1"
set "count=0"
if exist myapps.txt for /F "tokens=2 delims=:" %%I in (myapps.txt) do (
echo Getting path of app "%%I" ...
for /F "tokens=2 delims=:" %%J in ('adb.exe shell pm path "%%I" 2^>nul') do (
echo Path of app %%I is: "%%J"
rem Creating new folder for each app.
mkdir "apps_%input%\%%I" 2>nul
if exist "apps_%input%\%%I\" (
rem Pulling app from Android to PC.
echo Pulling app "%%I" to "apps_%input%\%%I" ...
adb.exe pull "%%J" "apps_%input%\%%I"
set /A count+=1
) else echo ERROR: Failed to create directory: "apps_%input%\%%I\"
)
)
if %count% == 1 (set "PluralS=") else set "PluralS=s"
echo Pulled %count% app%PluralS% from Android to PC.
endlocal
The outer FOR reads one line after the other from myapps.txt
. Each line is split up into substrings using the colon as delimiter because of option delims=:
. The first colon delimited substring is always package
which is of no interest for this task. Therefore the option tokens=2
is used to assign the second substring like com.flipkart.android
to the specified and case-sensitive loop variable I
.
The inner FOR loop starts in background one more command process with %ComSpec% /c
and the command line in the parentheses appended as additional argument. The output of adb
to handle STDOUT of the background command process is captured by FOR and processed line by line after started cmd.exe
closed itself after adb
terminated itself.
The single line output by adb
is again split up into substrings using colon as delimiter with assigning again just the second substring to specified loop variable J
.
Next a subdirectory is created with application name as directory name with redirecting the error message output on directory already existing or failed to create from handle STDERR to device NUL to suppress it.
Then an existence check for the just created directory is made to verify if it really exists and if this is the case the application is pulled from Android device to PC.
The help output on running cmd /?
in a command prompt window explains on last page that a file name (or any other argument string) containing a space or of these characters &()[]{}^=;!'+,`~
must be enclosed in double quotes. For that reason all argument strings referencing the value assigned currently to the loop variables I
(app name) and J
(app path) are enclosed in "
.
All echo
command lines and the last if
condition can be removed as they are just for getting some progress information during execution of the batch file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
if /?
mkdir /?
rem /?
set /?
setlocal /?
Read the Microsoft article about Using command redirection operators for an explanation of 2>nul
. The redirection operator >
must be escaped with caret character ^
on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded adb
command line with using a separate command process started in background.
Answered By - Mofi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.