📄 hx_moreprocesses.c
字号:
short theResult=0; while (noErr == (e = GetNextProcess (&psn))) { ProcessInfoRec info; info.processInfoLength = sizeof (info); info.processName = nil; info.processAppSpec = nil; if (noErr != (e = GetProcessInformation (&psn, &info))) break; if (AppSignature != info.processSignature) continue; theResult++; } /* while */ return (theResult); }//// ActivateApplication//void ActivateApplication(OSType AppSignature) { OSErr e = noErr; ProcessSerialNumber psn = {kNoProcess, kNoProcess}; while (noErr == (e = GetNextProcess (&psn))) { ProcessInfoRec info; info.processInfoLength = sizeof (info); info.processName = nil; info.processAppSpec = nil; if (noErr != (e = GetProcessInformation (&psn, &info))) break; if (AppSignature != info.processSignature) continue; ActivateApplicationPSN(&psn); break; } /* while */}//// ActivateApplicationPSN//void ActivateApplicationPSN(ProcessSerialNumber *psn) { if (psn == 0L) return; SetFrontProcess(psn);}//// FSpLaunchApplication launches a Mac application given a file spec//OSErr FSpLaunchApplication (FSSpec *appSpec) { return FSpLaunchApplicationWithParams(appSpec, NULL, NULL);}//// FSpLaunchApplication launches a Mac application given a file spec// and an option Apple Event to include as a launch parameter//// If psn is non-nil, the launched processes' PSN is returned//OSErr FSpLaunchApplicationWithParams(FSSpec *appSpec, const AppleEvent *theEvent, ProcessSerialNumber *psn){ return FSpLaunchApplicationWithParamsAndFlags(appSpec, theEvent, psn, (launchContinue | launchNoFileFlags)); }OSErr FSpLaunchApplicationWithParamsAndFlags(FSSpec *appSpec, const AppleEvent *theEvent, ProcessSerialNumber *psn, short launchFlags){ OSErr err = noErr; LaunchParamBlockRec launchPB; AEDesc paramsDesc; paramsDesc.dataHandle = NULL; launchPB.launchBlockID = extendedBlock; launchPB.launchEPBLength = extendedBlockLen; launchPB.launchFileFlags = 0; launchPB.launchControlFlags = launchFlags; launchPB.launchAppSpec = appSpec; launchPB.launchAppParameters = NULL; // if we were passed an event, convert and attach that to the launch param block if (theEvent) { err = AECoerceDesc(theEvent, typeAppParameters, ¶msDesc); if (err == noErr) {#if !defined(_CARBON) && !defined(_MAC_UNIX) HLock(paramsDesc.dataHandle);#endif launchPB.launchAppParameters = (AppParametersPtr) *paramsDesc.dataHandle; } } // do the launch if (err == noErr) { err = LaunchApplication(&launchPB); if (err == noErr && psn != NULL) { *psn = launchPB.launchProcessSN; } } // if we had an event to convert and attach, dispose our converted version if (paramsDesc.dataHandle) (void) AEDisposeDesc(¶msDesc); return err;}OSErr FSpLaunchApplicationPSN (FSSpec *appSpec,ProcessSerialNumber* psn) { return FSpLaunchApplicationWithParams(appSpec, NULL, psn); }//// OpenDocumentWithApplication sends an event to the target application// to open the document, launching the application if necessary.//// Unlike sending an Apple event to the finder, this gives us an// error if the open doesn't happen//OSErr OpenDocumentWithApplication(OSType signature, FSSpec *file){ OSErr err; ProcessSerialNumber appPSN; FSSpec appSpec; AEDesc targetAddrDesc; AppleEvent theAppleEvent, theReplyEvent; AliasHandle fileAlias; theAppleEvent.dataHandle = NULL; // to facilitate cleanup targetAddrDesc.dataHandle = NULL; appPSN.lowLongOfPSN = 0; fileAlias = NULL; err = GetPSNFromSignature(signature, &appPSN); if (err != noErr) { // app isn't running, we'll try to launch it // // address the event target by the process's signature err = AECreateDesc(typeApplSignature, &signature, sizeof(DescType), &targetAddrDesc); } else { // address target by PSN err = AECreateDesc(typeProcessSerialNumber, &appPSN, sizeof(ProcessSerialNumber), &targetAddrDesc); } if (err == noErr) { // make the Apple event, stuff in an alias to the file as the direct object err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &targetAddrDesc, kAutoGenerateReturnID, kAnyTransactionID, &theAppleEvent); if (err == noErr) { err = NewAliasMinimal(file, &fileAlias); if (err == noErr) { HLock((Handle) fileAlias); err = AEPutParamPtr(&theAppleEvent, keyDirectObject, typeAlias, *fileAlias, GetHandleSize((Handle) fileAlias)); } } } if (err == noErr) { if (appPSN.lowLongOfPSN) { // app is running and we know its PSN, so // send the event directly to it err = AESend(&theAppleEvent, &theReplyEvent, kAENoReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL); (void) SetFrontProcess(&appPSN); } else { // the app isn't running, so launch it with the // event attached err = FindApplicationBySignature(signature, &appSpec); if (err == noErr) { err = FSpLaunchApplicationWithParams(&appSpec, &theAppleEvent, NULL); } } } if (fileAlias) DisposeHandle((Handle) fileAlias); if (theAppleEvent.dataHandle) (void) AEDisposeDesc(&theAppleEvent); if (targetAddrDesc.dataHandle) (void) AEDisposeDesc(&targetAddrDesc); return err;}//// LaunchApplicationBySignature finds an application on a local // volume and launches it. theEvent can be null if no Apple// event should be attached.//OSErr LaunchApplicationBySignature(OSType signature, AppleEvent *theEvent){ OSErr err; FSSpec appSpec; err = FindApplicationBySignature(signature, &appSpec); if (err == noErr) { err = FSpLaunchApplicationWithParams(&appSpec, theEvent, NULL); } return err;}//// FindApplicationBySignature finds an application on a local (not server)// volume by checking the Desktop Databases of the mounted drives//// appSpec can be NULL if the caller is just interested in if the app// exists or not//OSErr FindApplicationBySignature(OSType signature, FSSpec *appSpec){#ifndef _MAC_UNIX Str63 name; short volIndex; short vRefNum; HParamBlockRec hpb; DTPBRec dtpb; GetVolParmsInfoBuffer gvpb; Boolean foundAppFlag; Boolean giveUpFlag;#endif OSErr err; #if defined(_CARBON) || defined(_MAC_UNIX) if (IsRunningNativeOnMacOSX()) { // Mac OS X; we can't rely on the desktop database, so use launch services FSRef appRef; err = GetApplicationFSRefFromSignature(signature, &appRef); if (err == noErr) { err = FSRefMakeFSSpec(&appRef, appSpec); } return err; }#endif #if defined(_MAC_UNIX) return -1; // should never get here#else foundAppFlag = false; giveUpFlag = false; // step through each volume available volIndex = 1; do { name[0] = 0; hpb.volumeParam.ioNamePtr = name; hpb.volumeParam.ioVolIndex = volIndex; hpb.volumeParam.ioVRefNum = 0; hpb.volumeParam.ioCompletion = NULL; // shouldn't matter since we're calling sync err = PBHGetVInfoSync(&hpb); if (err == noErr) { vRefNum = hpb.volumeParam.ioVRefNum; // check only local volumes for the application // // PBHGetVolParms returns vMServerAdr of zero for local volumes // // name and vRefNum are already set in param block hpb from the PBHGetVInfo call hpb.ioParam.ioBuffer = (char *) &gvpb; hpb.ioParam.ioReqCount = sizeof(GetVolParmsInfoBuffer); err = PBHGetVolParmsSync(&hpb); if (err == noErr && gvpb.vMServerAdr == 0) { // now we know this is a valid, local volume; // see if it has a desktop database dtpb.ioNamePtr = NULL; dtpb.ioVRefNum = vRefNum; err = PBDTGetPath(&dtpb); if (err == noErr) { // this volume has a desktop database; search it name[0] = 0; dtpb.ioNamePtr = name; dtpb.ioIndex = 0; // get newest application dtpb.ioFileCreator = signature; dtpb.ioCompletion = NULL; // shouldn't matter since we're calling sync // dtpb.ioDTRefNum set by GetPath call err = PBDTGetAPPLSync(&dtpb); if (err == noErr) { FSSpec foundSpec; err = FSMakeFSSpec(vRefNum, dtpb.ioAPPLParID, name, &foundSpec); if (err == noErr) { if (appSpec) *appSpec = foundSpec; // we got the app; bail foundAppFlag = true; } } } } } else { // PBHGetVInfoSync returned an error giveUpFlag = true; } volIndex++; } while (!giveUpFlag &&!foundAppFlag); // at this point, we should have noErr indicating that we found // an app and the FSSpec is valid return err;#endif // !defined _MAC_UNIX}OSErr SendQuitEventToApplication(ProcessSerialNumber *psn){ OSErr err; AEAddressDesc targetAddrDesc; AppleEvent theAppleEvent; AppleEvent replyAppleEvent; // address target by PSN err = AECreateDesc(typeProcessSerialNumber, psn, sizeof(ProcessSerialNumber), &targetAddrDesc); if (err == noErr) { // make the quit event err = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &targetAddrDesc, kAutoGenerateReturnID, kAnyTransactionID, &theAppleEvent); (void) AEDisposeDesc(&targetAddrDesc); } if (err == noErr) { // send it err = AESend(&theAppleEvent, &replyAppleEvent, kAENoReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL); (void) AEDisposeDesc(&theAppleEvent); } return err;}#if defined(_CARBON) || defined(_MAC_UNIX)OSStatus GetApplicationFSRefFromSignature(OSType signature, FSRef *outAppFSRef){ OSStatus err; const OSType kAnyFileType = kLSUnknownType; const CFStringRef kAnyExtension = NULL; CFURLRef* kDontWantURL = NULL; if (IsRunningNativeOnMacOSX()) { err = LSGetApplicationForInfo(kAnyFileType, signature, kAnyExtension, kLSRolesAll, outAppFSRef, kDontWantURL); } else { FSSpec appSpec; err = FindApplicationBySignature(signature, &appSpec); if (err == noErr) { err = FSpMakeFSRef(&appSpec, outAppFSRef); } } return err;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -