На форуме озвучил проблему, с получением переменной $(SiteURL) в Post-deployment Command Line для SharePoint проектов. Зачем это нужно, как получить значение этой переменной с помощью PowerShell и как поднять пул приложений после развертывания вашего решения из Visual Studio 2010, а не ждать отклика от IE 9 читайте в посте.
F5 в IE9
Во время разработки решения и особенно его отладки приходится часто выполнять развертывание пакета на локальную машину. В Visual Studio 2010 для этого предусмотрены встроенные средства под названием Active Deployment Configuration.
Список конфигураций может дополняться после установки расширений (например, CKSDev). Стандартная конфигурация (Default) выполняет следующий состав шагов:
1) Run Pre-Deployment Command;
2) Recycle IIS Application Pool (этот шаг необходим для загрузки обновленной сборки решения в пул приложения);
3) Retract Solution;
4) Add Solution;
5) Activate Features;
6) Run Post-Deployment Command;
Во время развертывания выполняется шаг (2) и пул приложений перезапускается. В этом и есть вся проблема. После развертывания необходимо нажимать F5 в браузере на странице сайта с целью его «оживить» и ждать обновления страницы (примерно 20 секунд, зависит от вашего локального компьютера). Достаточно утомительная операция, если выполнять развертывание больше десяти раз за день (а так и происходит, когда наращиваешь функционал).
Пришла мысль автоматизировать этот шаг. Для этого необходимо добавить команду отправки первого HTTP GET запроса к вашему сайту по адресу $(SiteURL) в Post-deployment Command Line.
Если воспользоваться инструментом TinyGet 5.2, то Post-deployment Command Line будет таким.
tinyget.exe -srv:localhost -uri:"$(SiteURL)" -h -auth:2 -loop:1 -u:CurrentUser
Проблема в том, что переменной $(SiteURL) нет. Список переменных можно посмотреть в статье Pre-build Event / Post-build Event Command Line Dialog Box или в настройках проекта.
О том, как получить значение $(SiteURL) и отправить первый HTTP GET запрос, описано ниже.
PowerShell
В Post-deployment Command Line можно вызывать PowerShell скрипты. Как это делать и для чего это может нужно описано в статье Visual Studio Pre / Post Deployment PowerShell for SharePoint.
Функция VS-SiteURL (чтение $(SiteURL) из конфигурации)
Значение $(SiteURL) храниться в файле $(ProjectName).user (настройки проекта с привязкой к пользователю).Задача очень простая, прочитать значение из этого файла. Реализация функции ниже. Как читать XML из PowerShell описано в статье Using PowerShell to read xml-files.
- function VS-SiteURL{
- <#
- .SYNOPSIS
- Read $(SiteURL) value from the user options file.
- .DESCRIPTION
- Read $(SiteURL) value from the user options file for Visual Studio 2010 SharePoint
- project. If the user options file does not exists, function will return empty string.
- .PARAMETER ProjectPath
- $(ProjectPath) the absolute path name of the project (defined with drive, path, base name,
- and file extension, see also http://msdn.microsoft.com/en-us/library/42x5kfw4.aspx).
- .OUTPUTS
- $(SiteURL) value.
- .EXAMPLE
- VS-SiteURL -ProjectPath:'C:\SPSample.csproj';
- .NOTES
- Revision History:
- 2012-03-12 : Roman Itakaev - Created.
- #>
- param(
- [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $ProjectPath
- )
- # the absolute path name of the user options file (.user file)
- $ProjectUserPath = $('{0}.user' -f $ProjectPath);
- # $(SiteURL) value
- $SiteURL = [String]::Empty;
- # .user file exists
- if(Test-Path -Path:$($ProjectUserPath)){
- # read xml (see also http://blogs.msdn.com/b/kalleb/archive/2008/07/19/using-powershell-to-read-xml-files.aspx)
- [xml]$ProjectUser = Get-Content -Path:$ProjectUserPath;
- # read $(SiteURL) value
- $SiteURL = $ProjectUser.Project.PropertyGroup.SharePointSiteUrl;
- }
- # $(SiteURL) value
- return $SiteURL;
- }
Можно воспользоваться инструментом TinyGet 5.2, как писал выше, а можно написать простейший код с использованием класса WebRequest. Подробнее описано в статье How to make a GET request by using Visual Basic .NET or Visual Basic 2005. Реализация функции ниже.
- function HTTP-Get{
- <#
- .SYNOPSIS
- Make a HTTP GET request to specified $(Url).
- .DESCRIPTION
- Make a HTTP GET request to specified $(Url) and dump $(Response) headers like
- tinyget.exe utility (see also http://support.microsoft.com/kb/840671).
- .PARAMETER Url
- $(Url) a address for request.
- .OUTPUTS
- No output.
- .EXAMPLE
- HTTP-Get -Url:'http://msdn.microsoft.com/en-us/';
- .NOTES
- Revision History:
- 2012-03-12 : Roman Itakaev - Created.
- #>
- param(
- [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $Url
- )
- # uniform resource identifier
- $Uri = New-Object -TypeName:'Uri' -ArgumentList:$Url;
- # web request
- $Request = [Net.WebRequest]::Create($Uri);
- # use default proxy
- $Request.Proxy = [Net.WebProxy]::GetDefaultProxy();
- # use default credentials
- $Request.UseDefaultCredentials = $true;
- # web response
- $Response = $null;
- # receive web response
- try{
- # receive web response from request
- $Response = $Request.GetResponse();
- } catch [Net.WebException]{
- <#
- Receive web response from exception (see also
- http://msdn.microsoft.com/en-us/library/system.net.webexception.response.aspx).
- #>
- $Response = $_.Exception.Response;
- }
- <#
- HTTP status code (see also
- http://msdn.microsoft.com/en-us/library/system.net.httpstatuscode.aspx).
- #>
- $StatusCode = $Response.StatusCode;
- <#
- Dump $(Response) like tinyget.exe utility (see also http://support.microsoft.com/kb/840671).
- #>
- # protocol
- Write-Host -Object:$('{0}/{1} {2} {3}' -f $Uri.Scheme.ToUpper(), `
- $Request.ProtocolVersion, [Int32]$StatusCode, $StatusCode);
- # headers
- $Response.Headers.Keys | ForEach-Object {
- # header
- Write-Host -Object:$('{0}: {1}' -f $_, $Response.Headers[$_]);
- }
- }
Функция SP-WakeUp (разбудить перезапущенный пул приложения)
Отправка первого запроса по адресу $(SiteURL)/_layouts/settings.aspx. Первый запрос на страницу Параметры сайта, потому что там удобно смотреть, что изменилось на сайте после активации возможности, или отладить активацию, если использовалась конфигурация No Activation.- function SP-WakeUp{
- <#
- .SYNOPSIS
- Read $(SiteURL) value from the user options file and make a HTTP GET
- request to site settings page ($(SiteURL)/_layouts/settings.aspx).
- .DESCRIPTION
- Read $(SiteURL) value from the user options file for Visual Studio 2010 SharePoint
- project and make a HTTP GET request to site settings page ($(SiteURL)/_layouts/settings.aspx).
- .PARAMETER ProjectPath
- $(ProjectPath) the absolute path name of the project (defined with drive, path, base name,
- and file extension, see also http://msdn.microsoft.com/en-us/library/42x5kfw4.aspx).
- .OUTPUTS
- No output.
- .EXAMPLE
- SP-WakeUp -ProjectPath:'C:\SPSample.csproj';
- .NOTES
- Revision History:
- 2012-03-12 : Roman Itakaev - Created.
- #>
- param(
- [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $ProjectPath
- )
- # site url
- $SiteURL = $(VS-SiteURL -ProjectPath:$ProjectPath).TrimEnd('/');
- # site url is not null or empty
- if($SiteURL){
- # site settings page address
- $Url = $('{0}/_layouts/settings.aspx' -f $SiteURL);
- # make HTTP GET request
- HTTP-Get -Url:$Url;
- }
- }
Скрипт SP-WakeUp.ps1
Все функции собраны в одном файле. Скачать скрипт можно по ссылке.Post-deployment Command Line
Венец всего этого программирования. Нам необходимо добавить скрипт SP-WakeUp.ps1 (скачать скрипт можно по ссылке) в корень проекта и прописать следующие команды в Post-deployment Command Line.
powershell.exe -Command "&{Set-ExecutionPolicy Unrestricted}" powershell.exe -Command "&{$(ProjectDir)SP-WakeUp.ps1 -ProjectPath:'$(ProjectPath)'}"ВАЖНО! Ваш проект должен лежать по пути, который НЕ содержит кириллицу, иначе будет ошибка.
Если ошибок нет, то журнал развертывания будет иметь вид.
Ремарка
Внимательный читатель заметил, что можно было «захардкодить» значение $(SiteURL) в Post-deployment Command Line изначально.
Можно и так, но тогда при переносе проекта на окружение другого разработчика пришлось бы корректировать эту строку, то есть менять настройки общего проекта под разработчика и его окружение (другой адрес сайта). Поэтому такой вариант не совсем приемлем.
Итоги
Пул приложений будет подниматься сразу после развертывания. Времени на развертывание пакета будет потрачено на 20 секунд больше, но нам не придется делать дополнительный шаг (F5 на странице и ожидание), что радует, когда нужно делать частое развертывание и отладку.

Решение красивое, но всё равно экономии времени нет, разве что если не пойти пить чай, а когда возвращаешься, то уже всё готово (не надо ждать долго реакции после нажатия F5)
ОтветитьУдалитьВремени тратится столько же, но зато сразу можно подключаться к рабочему процессу “w3wp.exe” и начинать отладку не выходя из IDE. Лишние клики отвлекают от решения задачи по предметной области. А так ты знаешь, Deploy без активации длится 30 секунд. Нажал одну кнопку, подождал, подключился к “w3wp.exe” и продолжай работать :)
ОтветитьУдалить