aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaphael <raphael@google.com>2011-11-11 10:43:03 -0800
committerRaphael <raphael@google.com>2011-11-11 14:17:33 -0800
commit58fd50795e20449fcf880022a9debbbcb2357376 (patch)
tree65ea6454b88409756cd6837d478391f2d7add357
parent560f2d0d14992389a367cbfef84b0e4a16796681 (diff)
downloadsdk-58fd50795e20449fcf880022a9debbbcb2357376.zip
sdk-58fd50795e20449fcf880022a9debbbcb2357376.tar.gz
sdk-58fd50795e20449fcf880022a9debbbcb2357376.tar.bz2
SDK Manager Windows: detach from java process.
This fixes 2 issues: - A bug in android.bat was that the bat+lib were only copied if the arguments were 'update sdk'. However since Tools R14 the sdkmanager doesn't use these arguments anymore. - Consequently when invoked as 'android sdk' it was not copying itself in the temp folder and thus was locking the tools folder, preventing updates. - The new behavior is to always copy, like that we don't care how the app is launched. - The SDK Manager.exe was launching android.bat and then waiting for it to finish, capturing its stdout in care there's an error to display. That locks SDK Manager.exe and thus prevent from updating it too. So instead we just don't wait for the bat to finish, don't capture/display its stdout. If there's an error, the user can still use the command line version to find out what's wrong. SDK Bugs: 21212:SDK Setup.exe [keeps] an open file handle SDK Bugs: 11989:SDK Manager.exe should be able to detach (it doesn't do the part where the sdk manager could restart itself after an update though. I'll file a different issue.) Change-Id: Id473ce58d3f36d417b6c0ee5f07a039adbbe06c0
-rw-r--r--avdlauncher/avdlauncher.c143
-rwxr-xr-xfiles/find_java.bat26
-rw-r--r--sdklauncher/sdklauncher.c141
-rwxr-xr-xsdkmanager/app/etc/android.bat13
4 files changed, 29 insertions, 294 deletions
diff --git a/avdlauncher/avdlauncher.c b/avdlauncher/avdlauncher.c
index ab2c88d..c3b21c1 100644
--- a/avdlauncher/avdlauncher.c
+++ b/avdlauncher/avdlauncher.c
@@ -18,7 +18,6 @@
* The "AVD Manager" is for Windows only.
* This simple .exe will sit at the root of the Windows SDK
* and currently simply executes tools\android.bat.
- * Eventually it should simply replace the batch file.
*
* TODO: replace by a jar-exe wrapper.
*/
@@ -69,137 +68,19 @@ void display_error(LPSTR description) {
}
-HANDLE create_temp_file(LPSTR temp_filename) {
-
- HANDLE file_handle = INVALID_HANDLE_VALUE;
- LPSTR temp_path = (LPSTR) malloc(MAX_PATH);
-
- /* Get the temp directory path using GetTempPath.
- GetTempFilename indicates that the temp path dir should not be larger than MAX_PATH-14.
- */
- int ret = GetTempPath(MAX_PATH - 14, temp_path);
- if (ret > MAX_PATH || ret == 0) {
- display_error("GetTempPath failed");
- free(temp_path);
- return INVALID_HANDLE_VALUE;
- }
-
- /* Now get a temp filename in the temp directory. */
- if (!GetTempFileName(temp_path, "txt", 0, temp_filename)) {
- display_error("GetTempFileName failed");
-
- } else {
- SECURITY_ATTRIBUTES sattr;
- ZeroMemory(&sattr, sizeof(sattr));
- sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
- sattr.bInheritHandle = TRUE;
-
- file_handle = CreateFile(temp_filename, // filename
- GENERIC_WRITE, // access: write
- FILE_SHARE_READ, // share mode: read OK
- &sattr, // security attributes
- CREATE_ALWAYS, // create even if exists
- FILE_ATTRIBUTE_NORMAL, // flags and attributes
- NULL); // template
- if (file_handle == INVALID_HANDLE_VALUE) {
- display_error("Create temp file failed");
- }
- }
-
- free(temp_path);
- return file_handle;
-}
-
-
-void read_temp_file(LPSTR temp_filename) {
- HANDLE handle;
-
- handle = CreateFile(temp_filename, // filename
- GENERIC_READ, // access: read
- FILE_SHARE_READ, // share mode: read OK
- NULL, // security attributes
- OPEN_EXISTING, // only open existing file
- FILE_ATTRIBUTE_NORMAL, // flags and attributes
- NULL); // template
-
- if (handle == INVALID_HANDLE_VALUE) {
- display_error("Open temp file failed");
- return;
- }
-
- /* Cap the size we're reading.
- 4K is good enough to display in a message box.
- */
- DWORD size = 4096;
-
- LPSTR buffer = (LPSTR) malloc(size + 1);
-
- LPSTR p = buffer;
- DWORD num_left = size;
- DWORD num_read;
- do {
- if (!ReadFile(handle, p, num_left, &num_read, NULL)) {
- display_error("Read Output failed");
- break;
- }
-
- num_left -= num_read;
- p += num_read;
- } while (num_read > 0);
-
- if (p != buffer) {
- *p = 0;
-
- /* Only output the buffer if it contains special keywords WARNING or ERROR. */
- char* s1 = strstr(buffer, "WARNING");
- char* s2 = strstr(buffer, "ERROR");
-
- if (s2 != NULL && s2 < s1) {
- s1 = s2;
- }
-
- if (s1 != NULL) {
- /* We end the message at the first occurence of [INFO]. */
- s2 = strstr(s1, "[INFO]");
- if (s2 != NULL) {
- *s2 = 0;
- }
-
- MessageBox(NULL, s1, "Android AVD Manager - Output", MB_OK);
- }
-
- }
-
- free(buffer);
-
- if (!CloseHandle(handle)) {
- display_error("CloseHandle read temp file failed");
- }
-}
-
-
-int avd_launcher() {
+int sdk_launcher() {
int result = 0;
STARTUPINFO startup;
PROCESS_INFORMATION pinfo;
CHAR program_dir[MAX_PATH];
int ret, pos;
- CHAR temp_filename[MAX_PATH];
- HANDLE temp_handle;
ZeroMemory(&pinfo, sizeof(pinfo));
- temp_handle = create_temp_file(temp_filename);
- if (temp_handle == INVALID_HANDLE_VALUE) {
- return 1;
- }
-
ZeroMemory(&startup, sizeof(startup));
startup.cb = sizeof(startup);
- startup.dwFlags = STARTF_USESTDHANDLES;
- startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- startup.hStdOutput = temp_handle;
- startup.hStdError = temp_handle;
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_HIDE|SW_MINIMIZE;
/* get path of current program, to switch dirs here when executing the command. */
ret = GetModuleFileName(NULL, program_dir, sizeof(program_dir));
@@ -235,29 +116,11 @@ int avd_launcher() {
if (!ret) {
display_error("Failed to execute tools\\android.bat:");
result = 1;
- } else {
- dprintf("Wait for process to finish.\n");
-
- WaitForSingleObject(pinfo.hProcess, INFINITE);
- CloseHandle(pinfo.hProcess);
- CloseHandle(pinfo.hThread);
}
}
dprintf("Cleanup.\n");
- if (!CloseHandle(temp_handle)) {
- display_error("CloseHandle temp file failed");
- }
-
- if (!result) {
- read_temp_file(temp_filename);
- }
-
- if (!DeleteFile(temp_filename)) {
- display_error("Delete temp file failed");
- }
-
return result;
}
diff --git a/files/find_java.bat b/files/find_java.bat
index 13cb74c..db1f949 100755
--- a/files/find_java.bat
+++ b/files/find_java.bat
@@ -24,10 +24,13 @@ rem http://technet.microsoft.com/en-us/library/bb490890.aspx
rem Check we have a valid Java.exe in the path. The return code will
rem be 0 if the command worked or 9009 if the exec failed (program not found).
rem Java itself will return 1 if the argument is not understood.
-set java_exe=java
+set java_exe=java.exe
+rem search it in the path and verify we can execute it
+for %%a in (%java_exe%) do set java_exe=%%~s$PATH:a
+if not exist %java_exe% goto SearchForJava
%java_exe% -version 2>nul
if ERRORLEVEL 1 goto SearchForJava
-goto :EOF
+goto :SearchJavaW
rem ---------------
@@ -49,7 +52,7 @@ echo Checking if Java is installed in %ProgramFiles%\Java.
set java_exe=
for /D %%a in ( "%ProgramW6432%\Java\*" ) do call :TestJavaDir "%%a"
-if defined java_exe goto :EOF
+if defined java_exe goto :SearchJavaW
rem Check for the "default" 64-bit version if it's not the same path
:Check64
@@ -59,7 +62,7 @@ echo Checking if Java is installed in %ProgramW6432%\Java instead (64-bit).
set java_exe=
for /D %%a in ( "%ProgramW6432%\Java\*" ) do call :TestJavaDir "%%a"
-if defined java_exe goto :EOF
+if defined java_exe goto :SearchJavaW
rem Check for the "default" 32-bit version if it's not the same path
:Check32
@@ -69,7 +72,7 @@ echo Checking if Java is installed in %ProgramFiles(x86)%\Java instead (32-bit).
set java_exe=
for /D %%a in ( "%ProgramFiles(x86)%\Java\*" ) do call :TestJavaDir "%%a"
-if defined java_exe goto :EOF
+if defined java_exe goto :SearchJavaW
:CheckFailed
echo.
@@ -104,3 +107,16 @@ echo - Under Windows Vista or Windows 7, open Control Panel / System / Advanced
echo At the end of the "Path" entry in "User variables", add the following:
echo ;%full_path%
echo.
+goto :EOF
+
+rem ---------------
+:SearchJavaW
+rem Called once java_exe has been set. Try to see if we can find a javaw
+rem to use. If not, we'll default to using java_exe.
+for %%a in (%java_exe%) do set p=%%~pa
+for %%a in (%java_exe%) do set n=%%~na
+for %%a in (%java_exe%) do set x=%%~xa
+set n=%n:java=javaw%
+set javaw_exe=%p%%n%%x%
+if not exist %javaw_exe% set javaw_exe=%java_exe%
+goto :EOF
diff --git a/sdklauncher/sdklauncher.c b/sdklauncher/sdklauncher.c
index 570da86..fd03d99 100644
--- a/sdklauncher/sdklauncher.c
+++ b/sdklauncher/sdklauncher.c
@@ -18,7 +18,6 @@
* The "SDK Manager" is for Windows only.
* This simple .exe will sit at the root of the Windows SDK
* and currently simply executes tools\android.bat.
- * Eventually it should simply replace the batch file.
*
* TODO: replace by a jar-exe wrapper.
*/
@@ -69,137 +68,19 @@ void display_error(LPSTR description) {
}
-HANDLE create_temp_file(LPSTR temp_filename) {
-
- HANDLE file_handle = INVALID_HANDLE_VALUE;
- LPSTR temp_path = (LPSTR) malloc(MAX_PATH);
-
- /* Get the temp directory path using GetTempPath.
- GetTempFilename indicates that the temp path dir should not be larger than MAX_PATH-14.
- */
- int ret = GetTempPath(MAX_PATH - 14, temp_path);
- if (ret > MAX_PATH || ret == 0) {
- display_error("GetTempPath failed");
- free(temp_path);
- return INVALID_HANDLE_VALUE;
- }
-
- /* Now get a temp filename in the temp directory. */
- if (!GetTempFileName(temp_path, "txt", 0, temp_filename)) {
- display_error("GetTempFileName failed");
-
- } else {
- SECURITY_ATTRIBUTES sattr;
- ZeroMemory(&sattr, sizeof(sattr));
- sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
- sattr.bInheritHandle = TRUE;
-
- file_handle = CreateFile(temp_filename, // filename
- GENERIC_WRITE, // access: write
- FILE_SHARE_READ, // share mode: read OK
- &sattr, // security attributes
- CREATE_ALWAYS, // create even if exists
- FILE_ATTRIBUTE_NORMAL, // flags and attributes
- NULL); // template
- if (file_handle == INVALID_HANDLE_VALUE) {
- display_error("Create temp file failed");
- }
- }
-
- free(temp_path);
- return file_handle;
-}
-
-
-void read_temp_file(LPSTR temp_filename) {
- HANDLE handle;
-
- handle = CreateFile(temp_filename, // filename
- GENERIC_READ, // access: read
- FILE_SHARE_READ, // share mode: read OK
- NULL, // security attributes
- OPEN_EXISTING, // only open existing file
- FILE_ATTRIBUTE_NORMAL, // flags and attributes
- NULL); // template
-
- if (handle == INVALID_HANDLE_VALUE) {
- display_error("Open temp file failed");
- return;
- }
-
- /* Cap the size we're reading.
- 4K is good enough to display in a message box.
- */
- DWORD size = 4096;
-
- LPSTR buffer = (LPSTR) malloc(size + 1);
-
- LPSTR p = buffer;
- DWORD num_left = size;
- DWORD num_read;
- do {
- if (!ReadFile(handle, p, num_left, &num_read, NULL)) {
- display_error("Read Output failed");
- break;
- }
-
- num_left -= num_read;
- p += num_read;
- } while (num_read > 0);
-
- if (p != buffer) {
- *p = 0;
-
- /* Only output the buffer if it contains special keywords WARNING or ERROR. */
- char* s1 = strstr(buffer, "WARNING");
- char* s2 = strstr(buffer, "ERROR");
-
- if (s2 != NULL && s2 < s1) {
- s1 = s2;
- }
-
- if (s1 != NULL) {
- /* We end the message at the first occurence of [INFO]. */
- s2 = strstr(s1, "[INFO]");
- if (s2 != NULL) {
- *s2 = 0;
- }
-
- MessageBox(NULL, s1, "Android SDK Manager - Output", MB_OK);
- }
-
- }
-
- free(buffer);
-
- if (!CloseHandle(handle)) {
- display_error("CloseHandle read temp file failed");
- }
-}
-
-
int sdk_launcher() {
int result = 0;
STARTUPINFO startup;
PROCESS_INFORMATION pinfo;
CHAR program_dir[MAX_PATH];
int ret, pos;
- CHAR temp_filename[MAX_PATH];
- HANDLE temp_handle;
ZeroMemory(&pinfo, sizeof(pinfo));
- temp_handle = create_temp_file(temp_filename);
- if (temp_handle == INVALID_HANDLE_VALUE) {
- return 1;
- }
-
ZeroMemory(&startup, sizeof(startup));
startup.cb = sizeof(startup);
- startup.dwFlags = STARTF_USESTDHANDLES;
- startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- startup.hStdOutput = temp_handle;
- startup.hStdError = temp_handle;
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_HIDE|SW_MINIMIZE;
/* get path of current program, to switch dirs here when executing the command. */
ret = GetModuleFileName(NULL, program_dir, sizeof(program_dir));
@@ -235,29 +116,11 @@ int sdk_launcher() {
if (!ret) {
display_error("Failed to execute tools\\android.bat:");
result = 1;
- } else {
- dprintf("Wait for process to finish.\n");
-
- WaitForSingleObject(pinfo.hProcess, INFINITE);
- CloseHandle(pinfo.hProcess);
- CloseHandle(pinfo.hThread);
}
}
dprintf("Cleanup.\n");
- if (!CloseHandle(temp_handle)) {
- display_error("CloseHandle temp file failed");
- }
-
- if (!result) {
- read_temp_file(temp_filename);
- }
-
- if (!DeleteFile(temp_filename)) {
- display_error("Delete temp file failed");
- }
-
return result;
}
diff --git a/sdkmanager/app/etc/android.bat b/sdkmanager/app/etc/android.bat
index 6f93c7b..56a3e99 100755
--- a/sdkmanager/app/etc/android.bat
+++ b/sdkmanager/app/etc/android.bat
@@ -42,16 +42,9 @@ set jar_path=lib\sdkmanager.jar;lib\swtmenubar.jar
rem Set SWT.Jar path based on current architecture (x86 or x86_64)
for /f %%a in ('%java_exe% -jar lib\archquery.jar') do set swt_path=lib\%%a
-if "%1 %2"=="update sdk" goto StartUi
-if not "%1"=="" goto EndTempCopy
-:StartUi
- rem Starting Android SDK and AVD Manager UI
-
- rem We're now going to create a temp dir to hold all the Jar files needed
- rem to run the android tool, copy them in the temp dir and finally execute
- rem from that path. We do this only when the launcher is run without
- rem arguments, to display the SDK Updater UI. This allows the updater to
- rem update the tools directory where the updater itself is located.
+:MkTempCopy
+ rem Copy android.bat and its required libs to a temp dir.
+ rem This avoids locking the tool dir in case the user is trying to update it.
set tmp_dir=%TEMP%\temp-android-tool
xcopy %swt_path% %tmp_dir%\%swt_path% /I /E /C /G /R /Y /Q > nul