Skip to content

Commit

Permalink
Merge pull request #35 from wjywbs/remove-app
Browse files Browse the repository at this point in the history
Fixes #35 - Add uninstall feature.
  • Loading branch information
shazron committed May 9, 2014
2 parents 9e52fd1 + cfb086e commit f728321
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 6 deletions.
2 changes: 2 additions & 0 deletions MobileDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ typedef int (*am_device_install_application_callback)(CFDictionaryRef, int);
mach_error_t AMDeviceInstallApplication(service_conn_t socket, CFStringRef path, CFDictionaryRef options, am_device_install_application_callback callback, void *user);
mach_error_t AMDeviceTransferApplication(service_conn_t socket, CFStringRef path, CFDictionaryRef options, am_device_install_application_callback callbackj, void *user);

int AMDeviceSecureUninstallApplication(int unknown0, struct am_device *device, CFStringRef bundle_id, int unknown1, void *callback, int callback_arg);

/* ----------------------------------------------------------------------------
* Semi-private routines
* ------------------------------------------------------------------------- */
Expand Down
71 changes: 65 additions & 6 deletions ios-deploy.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ int AMDeviceSecureInstallApplication(int zero, AMDeviceRef device, CFURLRef url,
int AMDeviceMountImage(AMDeviceRef device, CFStringRef image, CFDictionaryRef options, void *callback, int cbarg);
mach_error_t AMDeviceLookupApplications(AMDeviceRef device, CFDictionaryRef options, CFDictionaryRef *result);

bool found_device = false, debug = false, verbose = false, unbuffered = false, nostart = false, detect_only = false, install = true;
bool found_device = false, debug = false, verbose = false, unbuffered = false, nostart = false, detect_only = false, install = true, uninstall = false;
bool interactive = true;
char *app_path = NULL;
char *device_id = NULL;
Expand Down Expand Up @@ -813,6 +813,42 @@ void launch_debugger(AMDeviceRef device, CFURLRef url) {
}
}

CFStringRef get_bundle_id(CFURLRef app_url)
{
if (app_url == NULL)
return NULL;

CFURLRef url = CFURLCreateCopyAppendingPathComponent(NULL, app_url, CFSTR("Info.plist"), false);

if (url == NULL)
return NULL;

CFReadStreamRef stream = CFReadStreamCreateWithFile(NULL, url);
CFRelease(url);

if (stream == NULL)
return NULL;

CFPropertyListRef plist = NULL;
if (CFReadStreamOpen(stream) == TRUE) {
plist = CFPropertyListCreateWithStream(NULL, stream, 0,
kCFPropertyListImmutable, NULL, NULL);
}
CFReadStreamClose(stream);
CFRelease(stream);

if (plist == NULL)
return NULL;

const void *value = CFDictionaryGetValue(plist, CFSTR("CFBundleIdentifier"));
CFStringRef bundle_id = NULL;
if (value != NULL)
bundle_id = CFRetain(value);

CFRelease(plist);
return bundle_id;
}

void handle_device(AMDeviceRef device) {
if (found_device) return; // handle one device only
CFStringRef found_device_id = AMDeviceCopyDeviceIdentifier(device);
Expand Down Expand Up @@ -841,7 +877,29 @@ void handle_device(AMDeviceRef device) {

CFRelease(relative_url);

if (uninstall) {
printf("------ Uninstall phase ------\n");

CFStringRef bundle_id = get_bundle_id(url);
if (bundle_id == NULL) {
printf("Error: Unable to get bundle id from package %s\n Uninstall failed\n", app_path);
} else {
AMDeviceConnect(device);
assert(AMDeviceIsPaired(device));
assert(AMDeviceValidatePairing(device) == 0);
assert(AMDeviceStartSession(device) == 0);

assert(AMDeviceSecureUninstallApplication(0, device, bundle_id, 0, NULL, 0) == 0);

assert(AMDeviceStopSession(device) == 0);
assert(AMDeviceDisconnect(device) == 0);

printf("[ OK ] Uninstalled package with bundle id %s\n", CFStringGetCStringPtr(bundle_id, CFStringGetSystemEncoding()));
}
}

if(install) {
printf("------ Install phase ------\n");
printf("[ 0%%] Found device (%s), beginning install\n", CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding()));

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

while ((ch = getopt_long(argc, argv, "VmcdvunIi:b:a:t:g:x:p:", longopts, NULL)) != -1)
while ((ch = getopt_long(argc, argv, "VmcdvunrIi:b:a:t:g:x:p:", longopts, NULL)) != -1)
{
switch (ch) {
case 'm':
Expand Down Expand Up @@ -1000,6 +1060,9 @@ int main(int argc, char *argv[]) {
case 'p':
port = atoi(optarg);
break;
case 'r':
uninstall = 1;
break;
default:
usage(argv[0]);
return exitcode_error;
Expand All @@ -1020,10 +1083,6 @@ int main(int argc, char *argv[]) {
timeout = 5;
}

if (!detect_only) {
printf("------ Install phase ------\n");
}

if (app_path) {
assert(access(app_path, F_OK) == 0);
}
Expand Down

0 comments on commit f728321

Please sign in to comment.