Posted on 3. August 2017

Настройка Вашего приложения для входа в систему

В течение долгого времени пользователи ПК могли настроить приложения Win32 для запуска или входа в систему. Это также было возможно для приложений Desktop Bridge с момента обновления Windows 10 (v10.0.14393.0). Теперь Microsoft расширили эту функцию, чтобы в нее также вошли стандартные UWP приложения. Это доступно в сборках Insider Build 16226 и вместе с соответствующим SDK. В этом посте мы рассмотрим изменения кода, которые необходимо внести в манифест и в класс приложения для обработки сценария запуска, и то, как Ваше приложение может удовлетворять требования пользователей. 

Вот пример приложения, так называемого TestStartup - приложение предлагает кнопку для запроса включения режима запуска и сообщает текущий статус. Как правило, Вы добавляете такой вариант в какую-либо страницу настроек в приложении.

 

Прежде всего следует отметить, что Вы должны использовать расширение windows.startupTask Extension в манифесте приложения в узле «Extensions», который является сгенерированным узлом приложения. Ознакомьтесь с подробной информацией здесь. Такая же декларация расширения используется как для Desktop Bridge, так и для стандартных UWP приложений, но есть некоторые отличия.

 

  • Desktop Bridge доступен только на десктопе, поэтому он использует пространство имен XML для конкретного рабочего стола. Новая реализация UWP предназначена для использования, как правило, в UWP, поэтому использует общее пространство имен UAP (контрактная версия 5) - хотя в настоящее время он по-прежнему доступен только на рабочем столе.
  • Desktop Bridge EntryPoint должен быть «Windows.FullTrustApplication», тогда как для стандартного UWP это полное имя пространства имен Вашего класса приложения.
  • Приложения Desktop Bridge могут установить атрибут значения Enabled, а это означает, что приложение запустится при запуске без необходимости ручного включения. И наоборот, для стандратных UWP приложений этот атрибут игнорируется, а функция автоматически становится недоступной. Вместо этого пользователь должен сначала запустить приложение, и приложение должно запросить его включение для активации запуска.
  • Для приложений на Desktop Bridge разрешено несколько StartupTask расширений, каждый из которых может использовать другой исполняемый файл. И наоборот, для стандратных UWP приложений у Вас будет только одно исполняемое и одно StartupTask расширение.
Приложение Desktop Bridge 

xmlns:desktop="http://schemas.microsoft.com/
appx/manifest/desktop/windows10"
  
UWP приложение 

xmlns:uap5="http://schemas.microsoft.com/
appx/manifest/uap/windows10/5"
  

Для приложений Desktop Bridge и стандартных UWP приложений пользователь всегда находится под контролем и может в любой момент изменить Enabled состояние запуска Вашего приложения на вкладке «Startup» в Task Manager:

 

Также, для обоих типов приложений, приложение должно запускаться, по крайней мере, один раз, прежде чем пользователь сможет изменить состояния Disabled/Enabled. На самом деле это немного усложненно: если пользователь не запускает приложение, а затем пытается изменить состояние на «Enabled» в Task Manager, это скорее всего будет установлено. Однако, если Вы закроете Task Manager и снова откроете его, Вы будете видеть, что состояние по-прежнему отключено. Что же происходит? Task Manager сохраняет выбор пользователя в состоянии Enabled - но это фактически не позволяет приложению активироваться при запуске, если оно не будет запущено по крайней мере один раз - следовательно, это и есть причиной, по которой устанавливается состояние Disabled.

В Вашем UWP коде Вы можете установить запрос для включения при запуске. Для этого используйте метод StartupTask.GetAsync для инициализации объекта StartupTask (описанного здесь) - затем, перейдите в TaskId, указанного вами в манифесте, - и после этого, вызовите метод RequestEnableAsync. В тестовом приложении команда Microsoft делает это в обработчике Click. Возвращаемое значение запроса - это новый (возможно, неизменный) StartupTaskState

 

async private void requestButton_Click(object sender, RoutedEventArgs e)
{
    StartupTask startupTask = await StartupTask.GetAsync("MyStartupId");
    switch (startupTask.State)
    {
        case StartupTaskState.Disabled:
            // Task is disabled but can be enabled.
            StartupTaskState newState = await startupTask.RequestEnableAsync();
            Debug.WriteLine("Request to enable startup, result = {0}", newState);
            break;
        case StartupTaskState.DisabledByUser:
            // Task is disabled and user must enable it manually.
            MessageDialog dialog = new MessageDialog(
                "I know you don't want this app to run " +
                "as soon as you sign in, but if you change your mind, " +
                "you can enable this in the Startup tab in Task Manager.",
                "TestStartup");
            await dialog.ShowAsync();
            break;
        case StartupTaskState.DisabledByPolicy:
            Debug.WriteLine(
                "Startup disabled by group policy, or not supported on this device");
            break;
        case StartupTaskState.Enabled:
            Debug.WriteLine("Startup is enabled.");
            break;
    }
}

 

Поскольку приложения Desktop Bridge имеют компонент Win32, они работают с гораздо большей мощностью, чем стандартные UWP приложения. Они могут установить значение Enabled для StartupTask в манифесте и для этого не нужно вызывать API. Для стандатрных UWP приложений поведение более ограничено, в частности:

 

  • По умолчанию установлено значение «Disabled», поэтому в обычном случае пользователь должен запускать приложение хотя бы один раз - это дает приложению возможность запросить его включение.
  • Когда приложение вызывает RequestEnableAsync, в нем появится диалоговое окно «Пользовательское приглашение» для UWP приложений (или, если Вы вызываете его из компонента UWP в приложении на Desktop Bridge из Windows 10 Fall Creators Update). 
  • StartupTask включает метод Disable. Если состояние «Enabled», приложение может использовать API, чтобы поставить его на «Disabled». Если приложение затем снова запросит включение, это также вызовет приглашение пользователя.
  • Если пользователь отключает (либо через приглашение пользователя, либо через вкладку Startup в Task Manager), то приглашение снова не отображается, независимо от каких-либо запросов приложения. Конечно, приложение может разработать свои собственные пользовательские приглашения, попросив пользователя внести вручную изменения в Task Manager, но если пользователь точно отключил Ваш запуск, необходимо уважать его решение и убрать данные уведомления. В приведенном выше примере кода приложение реагирует на DisabledByUser, открывая свой собственный диалог сообщений - по желанию Вы можете это сделать, но следует подчеркнуть, что существует риск, что пользователю это не понравится.
  • Если функция отключена локальным администратором или политикой группы, то приглашение пользователя не отображается, а запуск не может быть активирован. Существующее перечисление StartupTaskState было расширено с новым значением DisabledByPolicy. Когда приложение увидит DisabledByPolicy, ему следует избегать повторного запроса, чтобы задача была включена, потому что запрос никогда не будет одобрен до тех пор, пока политика не изменится.
  • Платформы, отличные от Desktop, которые не поддерживают задачи запуска, также сообщают об отключенной функции.
Если запрос инициирует приглашение пользователя (только для UWP приложений), сообщение включает DisplayName, указанное в Вашем манифесте. Это приглашение не отображается, если при состояниях DisabledByUser или DisabledByPolicy.

Если Ваше приложение включено для активации при запуске, Вы должны обработать этот случай в Вашем классе приложения, переопределив метод OnActivated. Проверьте IActivatedEventArgs.Kind, чтобы узнать, является ли это ActivationKind.StartupTask, и если да, рассмотрите IActivatedEventArgs в StartupTaskActivatedEventArgs. Из этого, при необходимости, Вы можете получить TaskId. В данном тестовом приложении Microsoft просто передает ActivationKind как строку MainPage.

 

protected override void OnActivated(IActivatedEventArgs args)
{
    Frame rootFrame = Window.Current.Content as Frame;
    if (rootFrame == null)
    {
        rootFrame = new Frame();
        Window.Current.Content = rootFrame;
    }
 
    string payload = string.Empty;
    if (args.Kind == ActivationKind.StartupTask)
    { 
        var startupArgs = args as StartupTaskActivatedEventArgs;
        payload = ActivationKind.StartupTask.ToString();
    }
 
    rootFrame.Navigate(typeof(MainPage), payload);
    Window.Current.Activate();
}

 

Затем переопределение главной страницы OnNavigatedTo проверяет эту входящую строку и использует ее для сообщения статуса в пользовательском интерфейсе.

 

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    string payload = e.Parameter as string;
    if (!string.IsNullOrEmpty(payload))
    {
        activationText.Text = payload;
 
        if (payload == "StartupTask")
        {
            requestButton.IsEnabled = false;
            requestResult.Text = "Enabled";
            SolidColorBrush brush = new SolidColorBrush(Colors.Gray);
            requestResult.Foreground = brush;
            requestPrompt.Foreground = brush;
        }
    }
}

 

Обратите внимание, что при запуске приложения, оно запускается на панели задач с минимальным значением. В данном тестовом приложении при входе в обычный оконный режим приложение сообщает ActivationKind и StartupTaskState:

Используя windows.startupTask manifest Extension и StartupTask.RequestEnableAsync API, Ваше приложение может быть настроено для запуска при входе пользователя в систему. Это может быть полезно для приложений, которые пользователь будет использовать на постоянной основе - но эту функцию Вы должны использовать осторожно. Вам не следует использовать эту функцию, если Вы не ожидаете, что пользователь захочет ее использовать для Вашего приложения, и Вам следует избегать многократных уведомлений после того, как пользователь выберет именно Ваше приложение. Включение пользовательского запроса ставит пользователя под Ваше управление, что является улучшением по сравнению с более старой версией Win32.

Пример кода здесь.



Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading