Я нашел прямо сейчас решение с InternetExplorer.Application, которое работает после нескольких часов попыток и через 10 минут после постановки вопроса
Sub Test2()
'This will load a webpage in IE
Dim i As Long
Dim URL As String
Dim IE As Object
'Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
'Set IE.Visible = True to make IE visible, or False for IE to run in the background
IE.Visible = False
'Define URL
URL = "https://script.google.com/macros/s/AKfycbxU2ZL39IdtMzQXu0OLJZz3shSOx1JNTCbe1_SCxunIimLJVqY/exec"
'Navigate to URL
IE.Navigate URL
' Wait while IE loading...
'IE ReadyState = 4 signifies the webpage has loaded (the first loop is set to avoid inadvertently skipping over the second loop)
Do While IE.ReadyState = 4: DoEvents: Loop 'Do While
Do Until IE.ReadyState = 4: DoEvents: Loop 'Do Until
MsgBox (IE.document.body.innerText)
'Unload IE
Set IE = Nothing
End Sub
Я бы проверил файловую систему, если бинарный файл существует (в / Library / PrivilegedHelperTools и если plist существует в / Library / LaunchDaemons). Затем вы можете связаться со службой XPC и вызвать функцию ping, которая отвечает, если служба запущена и работает.
только мои 2 очка,
Роберт
Поскольку вы создаете вспомогательный инструмент, просто добавьте обработчик сообщений XPC, чтобы сообщить о состоянии вашего инструмента. Когда вы запустите, подключитесь и отправьте это сообщение. Если что-то из этого не получается, ваш инструмент установлен неправильно (или не отвечает).
В моем коде все мои службы XPC (включая моего привилегированного помощника) используют базовый протокол, используемый для тестирования и управления установками:
@protocol DDComponentInstalling /*<NSObject>*/
@required
- (void)queryBuildNumberWithReply:(void(^_Nonnull)(UInt32))reply;
@optional
- (void)didInstallComponent;
- (void)willUninstallComponent;
queryBuildNumberWithReply:
возвращает целое число, описывающее номер версии компонента:
- (void)queryBuildNumberWithReply:(void(^)(UInt32))reply
{
reply(FULL_BUILD_VERSION);
}
Если сообщение успешно, я сравниваю возвращаемое значение с константой номера сборки в моем приложении. Если они не совпадают, служба является более старой / более новой версией и должна быть заменена. Эта константа увеличивается с каждым публичным выпуском моего продукта.
Код, который я использую, выглядит примерно так:
- (BOOL)verifyServiceVersion
{
DDConnection* connection = self.serviceConnection;
id<DDComponentInstalling> proxy = connection.serviceProxy; // get the proxy (will connect, as needed)
if (proxy==nil)
// an XPC connection could not be established or the proxy object could not be obtained
return NO; // assume service is not installed
// Ask for the version number and wait for a response
NSConditionLock* barrierLock = [[NSConditionLock alloc] initWithCondition:NO];
__block UInt32 serviceVersion = UNKNOWN_BUILD_VERSION;
[proxy queryBuildNumberWithReply:^(UInt32 version) {
// Executes when service returns the build version
[barrierLock lock];
serviceVersion = version;
[barrierLock unlockWithCondition:YES]; // signal to foreground thead that query is finished
}];
// wait for the message to reply
[barrierLock lockWhenCondition:YES beforeDate:[NSDate dateWithTimeIntervalSinceNow:30.0];
BOOL answer = (serviceVersion==FULL_BUILD_VERSION); // YES means helper is installed, alive, and correct version
[barrierLock unlock];
return answer;
}
Обратите внимание, что DDConnection
- это служебная оболочка для соединений XPC, а трюк barrierLock
фактически инкапсулирован в общем методе - поэтому я не заканчивайте тем, что пишете это снова и снова - но развернуто здесь для целей демонстрации.
У меня также есть проблемы до / после установки / обновления, поэтому во всех моих компонентах реализованы необязательные методы didInstallComponent
и willUninstallComponent
, которые я отправляю сразу после установки нового помощника или непосредственно перед тем, как планирую удалить или заменить установленный помощник.