Skip to content

Commit f728321

Browse files
committed
Merge pull request #35 from wjywbs/remove-app
Fixes #35 - Add uninstall feature.
2 parents 9e52fd1 + cfb086e commit f728321

File tree

2 files changed

+67
-6
lines changed

2 files changed

+67
-6
lines changed

MobileDevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ typedef int (*am_device_install_application_callback)(CFDictionaryRef, int);
453453
mach_error_t AMDeviceInstallApplication(service_conn_t socket, CFStringRef path, CFDictionaryRef options, am_device_install_application_callback callback, void *user);
454454
mach_error_t AMDeviceTransferApplication(service_conn_t socket, CFStringRef path, CFDictionaryRef options, am_device_install_application_callback callbackj, void *user);
455455

456+
int AMDeviceSecureUninstallApplication(int unknown0, struct am_device *device, CFStringRef bundle_id, int unknown1, void *callback, int callback_arg);
457+
456458
/* ----------------------------------------------------------------------------
457459
* Semi-private routines
458460
* ------------------------------------------------------------------------- */

ios-deploy.c

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ int AMDeviceSecureInstallApplication(int zero, AMDeviceRef device, CFURLRef url,
125125
int AMDeviceMountImage(AMDeviceRef device, CFStringRef image, CFDictionaryRef options, void *callback, int cbarg);
126126
mach_error_t AMDeviceLookupApplications(AMDeviceRef device, CFDictionaryRef options, CFDictionaryRef *result);
127127

128-
bool found_device = false, debug = false, verbose = false, unbuffered = false, nostart = false, detect_only = false, install = true;
128+
bool found_device = false, debug = false, verbose = false, unbuffered = false, nostart = false, detect_only = false, install = true, uninstall = false;
129129
bool interactive = true;
130130
char *app_path = NULL;
131131
char *device_id = NULL;
@@ -813,6 +813,42 @@ void launch_debugger(AMDeviceRef device, CFURLRef url) {
813813
}
814814
}
815815

816+
CFStringRef get_bundle_id(CFURLRef app_url)
817+
{
818+
if (app_url == NULL)
819+
return NULL;
820+
821+
CFURLRef url = CFURLCreateCopyAppendingPathComponent(NULL, app_url, CFSTR("Info.plist"), false);
822+
823+
if (url == NULL)
824+
return NULL;
825+
826+
CFReadStreamRef stream = CFReadStreamCreateWithFile(NULL, url);
827+
CFRelease(url);
828+
829+
if (stream == NULL)
830+
return NULL;
831+
832+
CFPropertyListRef plist = NULL;
833+
if (CFReadStreamOpen(stream) == TRUE) {
834+
plist = CFPropertyListCreateWithStream(NULL, stream, 0,
835+
kCFPropertyListImmutable, NULL, NULL);
836+
}
837+
CFReadStreamClose(stream);
838+
CFRelease(stream);
839+
840+
if (plist == NULL)
841+
return NULL;
842+
843+
const void *value = CFDictionaryGetValue(plist, CFSTR("CFBundleIdentifier"));
844+
CFStringRef bundle_id = NULL;
845+
if (value != NULL)
846+
bundle_id = CFRetain(value);
847+
848+
CFRelease(plist);
849+
return bundle_id;
850+
}
851+
816852
void handle_device(AMDeviceRef device) {
817853
if (found_device) return; // handle one device only
818854
CFStringRef found_device_id = AMDeviceCopyDeviceIdentifier(device);
@@ -841,7 +877,29 @@ void handle_device(AMDeviceRef device) {
841877

842878
CFRelease(relative_url);
843879

880+
if (uninstall) {
881+
printf("------ Uninstall phase ------\n");
882+
883+
CFStringRef bundle_id = get_bundle_id(url);
884+
if (bundle_id == NULL) {
885+
printf("Error: Unable to get bundle id from package %s\n Uninstall failed\n", app_path);
886+
} else {
887+
AMDeviceConnect(device);
888+
assert(AMDeviceIsPaired(device));
889+
assert(AMDeviceValidatePairing(device) == 0);
890+
assert(AMDeviceStartSession(device) == 0);
891+
892+
assert(AMDeviceSecureUninstallApplication(0, device, bundle_id, 0, NULL, 0) == 0);
893+
894+
assert(AMDeviceStopSession(device) == 0);
895+
assert(AMDeviceDisconnect(device) == 0);
896+
897+
printf("[ OK ] Uninstalled package with bundle id %s\n", CFStringGetCStringPtr(bundle_id, CFStringGetSystemEncoding()));
898+
}
899+
}
900+
844901
if(install) {
902+
printf("------ Install phase ------\n");
845903
printf("[ 0%%] Found device (%s), beginning install\n", CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding()));
846904

847905
AMDeviceConnect(device);
@@ -929,6 +987,7 @@ void usage(const char* app) {
929987
" -v, --verbose enable verbose output\n"
930988
" -m, --noinstall directly start debugging without app install (-d not required)\n"
931989
" -p, --port <number> port used for device, default: 12345 \n"
990+
" -r, --uninstall uninstall the app before install (do not use with -m; app cache and data are cleared) \n"
932991
" -V, --version print the executable version \n",
933992
app);
934993
}
@@ -953,11 +1012,12 @@ int main(int argc, char *argv[]) {
9531012
{ "version", no_argument, NULL, 'V' },
9541013
{ "noinstall", no_argument, NULL, 'm' },
9551014
{ "port", required_argument, NULL, 'p' },
1015+
{ "uninstall", no_argument, NULL, 'r' },
9561016
{ NULL, 0, NULL, 0 },
9571017
};
9581018
char ch;
9591019

960-
while ((ch = getopt_long(argc, argv, "VmcdvunIi:b:a:t:g:x:p:", longopts, NULL)) != -1)
1020+
while ((ch = getopt_long(argc, argv, "VmcdvunrIi:b:a:t:g:x:p:", longopts, NULL)) != -1)
9611021
{
9621022
switch (ch) {
9631023
case 'm':
@@ -1000,6 +1060,9 @@ int main(int argc, char *argv[]) {
10001060
case 'p':
10011061
port = atoi(optarg);
10021062
break;
1063+
case 'r':
1064+
uninstall = 1;
1065+
break;
10031066
default:
10041067
usage(argv[0]);
10051068
return exitcode_error;
@@ -1020,10 +1083,6 @@ int main(int argc, char *argv[]) {
10201083
timeout = 5;
10211084
}
10221085

1023-
if (!detect_only) {
1024-
printf("------ Install phase ------\n");
1025-
}
1026-
10271086
if (app_path) {
10281087
assert(access(app_path, F_OK) == 0);
10291088
}

0 commit comments

Comments
 (0)