Russian Qt Forum
Ноябрь 22, 2024, 13:45 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: [Пост] Автозапуск под маком  (Прочитано 20401 раз)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« : Июль 18, 2012, 13:56 »

Нужно было реализовать в одном приложении автозапуск под мак ос, как всегда полез в интернет за полезной инфой. Полезного нашел не очень много, в основном холивар на тему: "А нафиг это нужно пускай юзверь сам делает". Сам не сам ,а задачу решать нужно, начал копать что есть,  и есть достаточно примеров с использованием Object-C. Я уже даже немного отчаялся, да есть технология впиливания Object-C кода в С++(Qt) код, но не хотелось это делать в небольшом проекте. В итоге узнал где хранить авторан в маке и у меня родилось вот такое решение для авторана под маком для Qt

Код:
    QSettings setting(QDir::homePath() + QDir::separator() + "Library/Preferences/loginwindow.plist",QSettings::NativeFormat);

    QDir dir(QCoreApplication::applicationDirPath());
    dir.cdUp();
    dir.cdUp();

    QVariantList lst = qvariant_cast<QVariantList >(setting.value("AutoLaunchedApplicationDictionary"));
    bool exist = false;
    for (int i = 0; i < lst.count(); ++i) {
        QVariantMap prop = qvariant_cast<QVariantMap >(lst[i]);

        if (prop["Path"] == dir.absolutePath()) {
            exist = true;
            break;
        }
    }

    if (exist == false) {
        QVariantMap v;
        v["Path"] = dir.absolutePath();
        v["Hidden"] = false;
        lst.append(v);
        setting.setValue("AutoLaunchedApplicationDictionary",lst);
    }
 

Выкладываю это решение так как сам потртил прилично времени на поиск, надеюсь кому то поможет Улыбающийся

P.S. Ссылка на верное решение
« Последнее редактирование: Март 24, 2014, 10:59 от ecspertiza » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Июль 18, 2012, 14:21 »

да есть технология впиливания Object-C кода в С++(Qt) код, но не хотелось это делать в небольшом проекте
это делается элементарно и не требует никаких танцев с бубном. не понимаю зачем использовать какие-то хаки если есть нормальное готовое решение.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #2 : Июль 18, 2012, 15:53 »

А можно на него посмотреть ?  Улыбающийся А то пришлось изобретать вот такую тему ибо решения найти неполучилось.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #3 : Июль 18, 2012, 16:24 »

и есть достаточно примеров с использованием Object-C
выкладывай пример Улыбающийся

Objective-C код помещаешь в файл .m (или .mm, если нужно еще и плюсовой код там вызывать) и добавляешь его в секцию OBJECTIVE_SOURCES в .pro
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #4 : Июль 18, 2012, 16:39 »

Ну я читал пост http://www.prog.org.ru/topic_13175_0.html и там Igors предлагал использовать LSSharedFileListInsertItemURL. Потом наткнулся на вот такой пример в инете http://cocoatutorial.grapewave.com/tag/lssharedfilelistinsertitemurl/

Тут еще есть один фактор небольшой, мне object-c глаз режет Улыбающийся Плюс ко всему не силен в нем, поэтому старался найти реализацию на Qt. Ну вроде как не плохо получилась, насколько понял dropbox тудаже пишет данные для авторана.

А насчет

Objective-C код помещаешь в файл .m (или .mm, если нужно еще и плюсовой код там вызывать) и добавляешь его в секцию OBJECTIVE_SOURCES в .pro

спасибо, нужно будет попробовать, всеравно придеться некоторые плюхи нативные писать. Читал как то на хабре статью там как то посложнее вроде было, мосты еще строили какие то.
« Последнее редактирование: Июль 18, 2012, 16:49 от ecspertiza » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #5 : Июль 18, 2012, 19:04 »

конкретно в данном случае Objective-C вообще не нужен – это всё сишные функции, а вместо Foundation (Objective-C) типов можно использовать CoreFoundation (сишные) типы. напишу переделанный код чуть позже.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #6 : Июль 18, 2012, 19:47 »

вот:
Код
C++ (Qt)
void addAppAsLoginItem
{
   // Create a reference to the shared file list.
   // We are adding it to the current user only.
   // If we want to add it all users, use
   // kLSSharedFileListGlobalLoginItems instead of
   // kLSSharedFileListSessionLoginItems
   LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
   if (loginItems)
   {
       // This will retrieve the path for the application
       // For example, /Applications/test.app
       CFURLRef bundleUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
 
       // Insert an item to the list.
       LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemLast, NULL, NULL, bundleUrl, NULL, NULL);
       if (item)
           CFRelease(item);
       else
           qDebug("failed to add login item");
 
       CFRelease(bundleUrl);
       CFRelease(loginItems);
   }    
   else
       qDebug("failed to obtain login items");
}
 
void deleteAppFromLoginItem
{
   // Create a reference to the shared file list.
   LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
   if (loginItems)
   {
       CFURLRef bundleUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
 
       // Retrieve the list of Login Items
       UInt32 seedValue;
       CFArrayRef loginItemsArray = LSSharedFileListCopySnapshot(loginItems, &seedValue);
 
       for (CFIndex i = 0, n = CFArrayGetCount(loginItemsArray); i < n; ++i)
       {
           LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(loginItemsArray, i);
           // Resolve the item with URL
           CFURLRef url;
           if (LSSharedFileListItemResolve(itemRef, 0, &url, NULL) == noErr)
           {
               bool shouldRemove = CFEqual(bundleUrl, url);
               CFRelease(url);
               if (shouldRemove)
               {
                   LSSharedFileListItemRemove(loginItems, itemRef);
                   break;
               }
           }
       }
 
       CFRelease(loginItemsArray);
       CFRelease(bundleUrl);
       CFRelease(loginItems);
   }
}

но в документации я наткнулся на вот такую штуку:
Цитировать
Creating a Login Item for Your App

To create a login item for your sandboxed app, use the SMLoginItemSetEnabled function (declared in ServiceManagement/SMLoginItem.h) as described in “Adding Login Items Using the Service Management Framework” in Daemons and Services Programming Guide.

(With App Sandbox, you cannot create a login item using functions in the LSSharedFileList.h header file. For example, you cannot use the function LSSharedFileListInsertItemURL. Nor can you manipulate the state of launch services, such as by using the function LSRegisterURL.)
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #7 : Июль 18, 2012, 20:01 »

спасибо за пример, позновательно. Думаю после прочтения маковской доки многие вопросы отпадут  Улыбающийся
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #8 : Март 20, 2014, 14:26 »

Пожалуй займусь "некрофилией"  Улыбающийся Так как для меня сейчас этот вопрос критичный, имею ввиду автозапуск софта, описал процесс того как правильно делать автозапуск под маком
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #9 : Март 20, 2014, 15:14 »

1) в одном случае ты тупо по-сишному приводишь тип, в другом — через бридж. уж определись Улыбающийся
2) алерты можно запускать одной строкой, нет нужды заводить для этого переменную (ну это больше вопрос стиля). у тебя много переменных, которые используются лишь раз.
3) boundle
4) alreadyRunning = YES; — думаю можно брейк поставить следующей строкой Улыбающийся еще чуть удобнее можно перечислить массив через enumerateWithBlock (или как-то так, не помню точное название метода)
5) удаление части пути — это извращение какое-то, нельзя как-то по-проще написать?
6) performSelector:withObject:afterDelay: — неужто GCD нельзя использовать? performSelectorы эти — уже прошлый век.
7) ну и ссылку не помешает добавить в первый пост Подмигивающий
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #10 : Март 24, 2014, 10:59 »

1. Спасибо, исправил на __bridge - по идее это более верное решение.
2. Подскажи пожалуйста как в одну строчку вызывать ? В примерах обычно как у меня, а мне это самому не очень нравится.
3. Моя вина, исправил.
4. Согласен, сэкономит времени, да и по кодингу будет правильнее.
5. Не представляю как, может если только где то путь хранить к приложению. Не будем же мы надеяться на то, что у всех софт лежит в Applications Улыбающийся
6. Расскажешь в чем разница ? Почему предпочтительнее использовать GCD.
7. Ссылку добавил Улыбающийся
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #11 : Март 24, 2014, 13:51 »

2)
Код
C (Mac)
[[NSAlert alertWithMessageText:@"An error ocurred"
                                        defaultButton:@"OK"
                                      alternateButton:nil
                                          otherButton:nil
                            informativeTextWithFormat:@"LSRegisterURL failed"] runModal];
5) а в чем суть этого кода? напиши пример входа и выхода. и разве bundlePath не путь к .app возвращает?
6) на вопрос «почему» толком не отвечу, лучше почитай в эппловской документации. GCD — это более низкоуровневый механизм многопоточности, работающий с блоками вместо селекторов.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #12 : Март 24, 2014, 14:29 »

2. Спасибо, поправлю у себя.
5. Да bundlePath вернет путь к приложению, но он вернет путь к приложению лаунчеру, а нам нужно запустить сам софт. Не совсем понял насчет входа\выхода.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #13 : Март 24, 2014, 14:32 »

в посте из последнего куска кода: вход — path, выход — newPath. и аналогично для appPath.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Март 24, 2014, 15:09 »

[off]Мне тоже приходится делать вещи такого рода, но я всячески увертываюсь и избегаю их до последней возможности - ну только когда уже совсем прижмет... Наблюдая энтузиазм с которым молодые люди очертя голову прямо-таки бросаются в пучину этого кала, хочу заметить: изучение нативняка/потрохов ОС мало что дает программисту. Ну вот я усердно учил "classic" полагая что "свой ОС  надо знать" и все такое. Но пришел Carbon. Тут я уже сообразил и примкнул к кросс-платформенному API (к сожалению не Qt). Ага, ну вот и Carbon на ладан дышит, надо учить какаву. И конца-края этому не будет. Лучше впечатлять содержательностью/ф-ционалом задачи, а всякие "сервисы" - переживет, поверьте, он не оценит их высоко. 
[/off]
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.089 секунд. Запросов: 22.