Как приложение с однократным нажатием определяет его идентификатор приложения?

У меня есть однократное приложение, которое правильно подписано, правильно настроено и само устанавливает без каких-либо проблем.

Он настроен на запуск в автономном режиме, но устанавливается с определенного URL-адреса, и если я загружу и запустил setup.exe, он установит обновления.

Итак, это в основном все работает... кроме того, что я не могу распечатать номер версии или вызвать обновление из кода. Если я попытаюсь, я получаю страх: "Идентификатор приложения не установлен".

2017-01-10 13:43:14.8367 ERROR System.Deployment.Application.InvalidDeploymentException: Application identity is not set.
   at System.Deployment.Application.ApplicationDeployment.get_CurrentDeployment()
   at LibDataAgent.Internal.Services.UpdateService.Deployment() System.Deployment.Application.InvalidDeploymentException: Application identity is not set.
   at System.Deployment.Application.ApplicationDeployment.get_CurrentDeployment()
   at LibDataAgent.Internal.Services.UpdateService.Deployment()

Я не работаю в режиме отладки или использую отладочную сборку.

Итак, вот мой реальный вопрос:

Как, определяет ли код щелчка в System.Deployment.Application во время выполнения определение того, что является идентификатором приложения?

Итак, в этом есть много других вопросов, но, пожалуйста, не закрывайте это как дубликат, насколько я могу судить, это не одно.

Вот список вещей, на которые я не хочу отвечать:

  • Как подписать приложение click-one.
  • Как установить идентификатор приложения при его создании.
  • Как найти, где установлено приложение для кликов.
  • Как сделать работу с кликом одним приложением во время отладки.
  • Как проверить наличие обновлений с помощью ApplicationDeployment.

Просто очень ясно, что именно делает приложение с щелчком мыши во время выполнения, которое позволяет определить идентификатор приложения.

Help!

Примечания

Мои (до сих пор бесплодные) попытки решить эту проблему дали следующие заметки:

Я уверен, что это связано с тем, как запускается приложение, поскольку выполнение приложений из командной строки никогда не срабатывало с кликом; но выполнение одного и того же приложения из меню "Пуск" будет правильно возвращать IsNetworkDeployed как true.

Однако я не смог определить, что такое техническая разница, или почему вы правильно устанавливаете установку, а другая нет. (или действительно, почему это конкретное приложение не работает из меню "Пуск" , когда другие не имеют очевидной разницы).

Вещи, которые я пробовал, которые не имеют значения, включают:

  • рабочий каталог для приложения.
  • запуск приложения .exe напрямую или через оболочку
  • запуск приложения из нового ярлыка

Существует некоторая магия для "MyApplication.appref-ms", которая входит в меню "Пуск" ; appref-ms - это всего лишь URL-адрес пути установки:

http://s3-ap-southeast-1.amazonaws.com/blahblah/Dev/MyApplication.application#MyApplication.application, Culture=neutral, PublicKeyToken=fdasdfsafads, processorArchitecture=x86

... который каким-то образом запускает экземпляр приложения "click once aware". Но как?

Ответ 1

Я по-прежнему с радостью соглашусь с ответом, в котором объясняется, как кишки запуска приложения на самом деле устанавливают контекст приложения с личностью, но сейчас я лучше всего нарежу то, что происходит для тех, кто находит этот вопрос позже:

  • Приложения ClickOnce запускаются путем нажатия на URL-адрес установки или с помощью файла .appref-ms в меню "Пуск", содержащего URL-адрес.

  • Обработчик типа application/x-ms-application MIME вызывается для загруженного файла, который запускает экземпляр "ClickOnce aware" приложения.

  • Во время выполнения ApplicationContext.Identity используется для определения того, что представляют данные ClickOnce, и настройте объект CurrentDeployment.

  • Насколько известно, непосредственный запуск развернутого исполняемого файла для приложения ClickOnce (в C:\Users\Administrator\AppData\Local\Apps\2.0\b107ee1... или любой другой папки установки) будет всегда возвращает IsNetworkDeployed как false и не сможет самостоятельно обновиться.

Практически это означает:

  • Вы ищете папку установки и путь к вашему .exe? Не беспокойтесь. Даже когда вы знаете, где он находится, у него не будет правильного ApplicationContext при его запуске.

  • Чтобы создать новый экземпляр "ClickOnce aware" вашего приложения, запустите Internet Explorer на своем установочном URL-адресе. Вы не можете передавать ему аргументы командной строки.

например.

var url = "http://s3-ap-southeast-1.amazonaws.com/blahblah/Dev/MyApplication.application#MyApplication.application, Culture=neutral, PublicKeyToken=fdasdfsafads, processorArchitecture=x86";
var psi = new ProcessStartInfo
{
    FileName = @"iexplore",
    Arguments = $"\"{url}\"",
};
Process.Start(psi);

(если вы хотите найти URL-адрес, зайдите в меню "Пуск" для файла appref-ms для приложения, в нем содержится URL-адрес)

... и как исполняемый файл запускается с идентификатором?

Не знаю; но это настолько, насколько кажется, когда-либо, с пониманием этого:

(TL;DR; magic. Возможно, что-то связано с тем, как вызывается CreateProcess, чтобы вызвать аппликацию с помощью ApplicationContext api, в некоторой комбинации DFsvc.exe. DFshim.dll и DFdll.dll)

(Остальная часть этой информации взята из этого старого сообщения в блоге Яна Пикнела: http://ianpicknell.blogspot.com.au/2010/03/launching-clickonce-application.html)

Как только манифест развертывания сохраненный в папке Temporary Internet Files, Internet Explorer затем пытается установить, как он должен обрабатывать файл с помощью и фактическое). расширение приложения. Он проверяет пользовательский файл типы в HKCU\Software\Classes и, если не удается найти. подпрограмм .plplication, проверяет типы файлов, зависящих от машины, в HKCR. Благодаря этому он устанавливает, что расширение .plplication обозначает файл Application.Manifest. Затем он использует эту информацию для проверьте пользовательский HKCU\Software\Classes\Application.Manifest и машинные HKCR\Application.Manifest ключи для установки CLSID библиотеки, которая обрабатывает файлы Application.Manifest и выводит результат {98af66e4-aa41-4226-b80f-0b1a8f34eeb4}. Наконец, он смотрит вверх этот CLSID в пользовательском HKCU\Software\Classes\CLSID {98af66e4-aa41-4226-b80f-0b1a8f34eeb4} и машинный HKCR\CLSID {98af66e4-aa41-4226-b80f-0b1a8f34eeb4} пути для установления того, что файлы .application обрабатываются C:\WINDOWS\system32\DFshim.dll.

Здесь все начинает немного усложняться. Я сказал ранее что никакой "магии" не было за кулисами. Ну, пока это было true для процесса получения манифеста развертывания. конечно, не относится к процессу фактического запуска Приложение ClickOnce после того, как манифест развертывания был извлечен и обработчик DFshim.dll был идентифицирован.

DFshim.dll описывается в реестре как "Manifest mime handler", хотя его свойства файла описывают его как "Приложение Библиотека поддержки развертывания". Он реализует MIME Internet Explorer обработчик COM-интерфейса. Это родная 32-разрядная DLL, написанная в Microsoft Visual С++ 2005 и был установлен в C:\Windows\system32, когда .NET Framework 2.0 был установлен.

DFshim.dll имеет жестко закодированную ссылку на DFdll.dll, которую он находит путем проверки значений HKLM\SOFTWARE\Microsoft.NETFramework\InstallRoot (обычно C:\Windows\Microsoft.NET\Framework) и клавиши внизу HKLM\SOFTWARE\Microsoft.NETFramework\Policy\AppPatch (обычно v2.0.50727, даже если установлена ​​более поздняя версия Framework). DFdll.dll тоже является родной 32-разрядной DLL, написанной в Microsoft Visual С++ 2005.

DFdll.dll использует COM-службы, открытые DFsvc.exe, что также расположенный в папке .NET Framework. DFsvc.exe является стандартным .NET. Сборка MSIL. DFsvc содержит единственный основной метод (в пределах System.Deployment.Application), которое просто вызывает Внутренняя система .Deployment.Application.DFServiceEntryPoint.Initialize метод в System.Deployment.dll. Регистры метода инициализации System.Deployment.Application.DeploymentServiceCom с COM через System.Runtime.InteropServices.RegistrationServices(т.е. Выполняет эквивалент CoRegisterClassObject в COM) с использованием CLSID {33246f92-d56f-4e34-837a-9a49bfc91df3}. Это средство, с помощью которого его услуги доступны для DFdll.dll.

Служба COM, предоставляемая System.Deployment.Application.DeploymentServiceCom делегирует большинство его методов для других классов, отличных от ComVisible, в пределах Пространство имен System.Deployment.Application. Например, общественность Метод ActivateDeployment вызывает ActivateDeployment на новом Экземпляр System.Deployment.Application.ApplicationActivator, Открытый метод CheckForDeploymentUpdate вызывает CheckForDeploymentUpdate в System.Deployment.Application.SubscriptionStore и т.д.

Понятно, что подавляющее большинство работ, связанных с фактическим установка и запуск приложения ClickOnce осуществляется классов в пространстве имен System.Deployment, размещенных внутри DFsvc.exe. DFshim.dll и DFdll.dll в первую очередь отвечают для арбитража между COM-основанной сетью Internet Explorer и основанный на .NET мир ClickOnce.