четверг, июня 23, 2011

Веб-часть XmListViewer 2010

На базе версии XmListViewer 2007 сделал веб-часть XmListViewer 2010 для работы на фермах Sharepoint 2010. Собственно, практически только рефакторинг кода да использование некоторых фич SPF 2010 и понравившихся функциональных приёмчиков. Расширил функциональность light-версии – теперь можно получать данные одновременно из двух списков.

Функциональное нововведение одно - консолидация данных списков на узлах Шарепойнт на манер стандартной веб-части “Запрос контента” с некоторыми расширениями (или уходами в сторону?).

В процессе реализации преисполнился благодарностей (надеюсь, от икоты никто не умер…) разработчикам Sharepoint, исключившим из него возможность параллельного исполнения кода (в WSS 2007 такая возможность была с использованием ParallelExtensions-CTP, теперь она включена в .NET 4.0, с которым разработчики Sharepoint подружиться не сумели Печальная рожица) – при консолидации списков набирается много, а запрос данных дорог и прямо напрашивается на параллельное исполнение…

Ко всем прочим удовольствиям добавилась новелла с нерабочим редактором страниц на officelive.com (может, и починят, может, и навсегда…). Поэтому отдельную страничку сделать пока не удаётся, ссылки на закачку здесь – Light-версия веб-части, инструкция по установке и настройке.

Добавил:
Фокус с отдельной страничкой удался - http://dyakov.design.officelive.com/xmliv2010.aspx. Там кроме прочего все необходимые ссылки.

Technorati Tags:

пятница, июня 10, 2011

И тут сюрпризы...

На этот раз с датой/временем:
"От чего зависит, будет ли время выводиться с ведущим нулем, или без?

В Regional Settings есть локаль веба, есть таймзона, есть с какого дня начинается неделя, переключение между 12/24 форматом... Понять закономерность не удается. Для одной и той же локали 1033, таймзоны Пасифик ЮС, недели с понедельника и 24-х часового формата ведущий ноль может как показываться, так и исчезать. Сменил неделю на понедельничную - ноль вылез. Вернул обратно на воскресенскую - не пропал."

четверг, июня 09, 2011

Собиратель сюрпризов

Ширятся наши ряды – появился ещё один собиратель всякой бяки от Шарепойнта. Палец вверх Нельзя не поприветствовать!

Соберу до кучи его результаты здесь:

  1. формы InfoPath
  2. wsp-пакет
  3. мастер-страницы
  4. ContentType definition

Думаю, со временем список продолжится… Громко смеюсь



воскресенье, мая 01, 2011

Размещение общего Sharepoint-кода

Часто бывает удобно выделить общий для нескольких проектов код в отдельную сборку и подключать её к проектам. Собственно, так же, как и чей-то чужой код в виде готовой сборки (с codeplex.com и подобных ресурсов).

При этом сразу же встаёт во весь рост проблема размещения такого общего кода. Очевидное, простое и поэтому неправильное решение, быстро приходящее в голову – поместить общие сборки в пакет каждого использующего их проекта – отметается после удаления одного из таких пакетов. Общие сборки тоже удаляются и остальные решения перестают работать. Схожу с ума от злости

Попытки использовать имеющиеся под рукой установщики (Установщик Visual Studio 2010, Wix Toolset 3.5, InstallShield LE, установщик 7-zip и т.п.) оказались плачевными – либо пользоваться неудобно, либо не имеет нужной функциональности, либо не умеет обновлять ранее установленные сборки. Мрак какой-то… Палец вниз

Лучшим вариантом оказался собранный вручную wsp-пакет в сопровождении двух cmd-файлов для установки и обновления.

Описание пакета в файле makecab.ddf:

.OPTION EXPLICIT                    ; Generate errors on variable typos
.Set CabinetNameTemplate=SP.Shared.Assemblies.wsp ; The name of the WSP file
.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory
.Set CompressionType=MSZIP
.Set Cabinet=on
.Set Compress=on
.Set DiskDirectory1=.
.Set CabinetFileCountThreshold=0
.Set FolderFileCountThreshold=0
.Set FolderSizeThreshold=0
.Set MaxCabinetSize=0
.Set MaxDiskFileCount=0
.Set MaxDiskSize=0

SharedAssembly.dll
SharedAssembly2.dll
...
manifest.xml

Файл manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<Solution xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
SolutionId="guid..."
xmlns="http://schemas.microsoft.com/sharepoint/">
<Assemblies>
<Assembly Location="SharedAssembly.dll" DeploymentTarget="GlobalAssemblyCache"/>
<Assembly Location="SharedAssembly2.dll" DeploymentTarget="GlobalAssemblyCache"/>
</Assemblies>
</Solution>

Собирается пакет командой makecab /v1 /f makecab.ddf, устанавливается файлом _install.cmd :

@set prompt=$g
@set spver=14
@set wsp=SP.Shared.Assemblies.wsp
@set admpgm="%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\%spver%\BIN\STSADM.EXE"
@time /t
%admpgm% -o addsolution -filename %wsp%
%admpgm% -o deploysolution -name %wsp% -allowCasPolicies -allowGacDeployment -immediate -force
@pause
%admpgm% -o execadmsvcjobs

Для обновления используем файл _upgrade.cmd :

@set prompt=$g
@set spver=14
@set wsp=SP.Shared.Assemblies.wsp
@time /t
@set admpgm="%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\%spver%\BIN\STSADM.EXE"
%admpgm% -o upgradesolution -name %wsp% -filename %wsp% -immediate -allowCasPolicies -allowGacDeployment
pause
%admpgm% -o execadmsvcjobs

Конечно, в соответствии с новомодными тенденциями можно применить PowerShell, но некоторым так привычней Шучу

Technorati Tags:


пятница, апреля 08, 2011

F#, первая серия.

Дал себе задание (довольно давно уже) при появлении возможностей заняться изучением новомодного языка. С первого взгляда - всё есть: поддержка Студии (хоть 2008, хоть 2010), полно литературы (правда, вся английская, но так даже и лучше).

Переносить из книжек всякие примеры - скучно, поэтому решил начать делать одновременно и второе обещанное себе дело - перенести имеющуюся у меня утилиту для работы с Шарепойнтом в ФАР (с использованием техники .NET-плагинов).

Борьба продолжалась почти два световых дня и осложнялась скудной документацией по Far.Net (та самая поддержка .NET-плагинов, к появлению которой когда-то имел достаточнно близкое отношение). Дело, конечно, естественное (человек разрабатывает систему практически в одиночку и добровольно), обижаться не на что...

Удивительней положение с изучаемым языком: синтаксис у него оказался достаточно заковыристым, чтоб постоянно спотыкаться, поддержка редактором Студии не в пример слабее таковой для C#. Показывать классы и прочие объекты в FS-сборке студия отказывается (Рефлектор, однако, показывает картинку, весьма похожую на правду). Подписывать сборку проект FS-библиотеки даже и не предлагает, а я как-то привык за 6 лет занятий разработкой под Шарепойнт любой проект начинать с настройки размещения, которого без строгого имени не бывает...

Добила необходимость ручного регулирования порядка размещения файлов в проекте и объектов (функций, классов и т.д.) в файле Увядшая роза. Пока к такому не готов, а файлов/объектов намечается довольно много...

Ладно, кое-какой опыт получился, попозже можно будет и вернуться...

P.S. Совсем уж остановил вот такой фокус…



понедельник, марта 07, 2011

Хвала Reflection.

Потребовалось в проекте выгружать на диск документы из библиотек Шарепойнт. На первый взгляд – ничего особенного: запрашиваем у пользователя путь к папке сохранения на манер модуля резервного копирования в Центре Управления, подключаем пространство имён System.IO, класс DirectoryInfo, методы CreateSubdirectory, file.OpenBinary() + stream.Write() – и все дела. На второй взгляд – тоже просто: примеры решения подобных задач имено так и сделаны. На третий взгляд – вообще всё замечательно: после компиляции код работает, документы выгружает. Ура.

Хуже на четвёртый взгляд, взгляд тестировщика – не выгружаецца! Целевая папка как бы недоступна… Нда… Модуль резервного копирования в ту же папку спокойно свои файлы сохраняет… При помощи отладчика можно наблюдать, как конструктор

 new DirectoryInfo(path)
без выбрасывания каких-либо исключений возвращает непустой объект (что и ожидается), у которого свойство Exists == false. Сюрприз, фокус-покус.

Фокус разоблачается разглядыванием в Рефлекторе или IL-шпионе (ILSpy) кода классов из пространства Microsoft.SharePoint.Administration.Backup. Там методы System.IO используются примерно так:

using (SecurityContext.RevertToSelf())
{
info = new DirectoryInfo(dir);
}

Класс Microsoft.SharePoint.Utilities.SecurityContext почему-то “внутренний”, использовать как обычно его не получится, но для Reflection преград же нет… Дразнюсь

Technorati Tags: , ,

Печальное будущее Silverlight?

Вообще-то, собирался написать заметку про Internet Explorer 9, какой он падучий в версии RC – гораздо более падучий, нежели был в версии “бета” (уже отправил несчётное количество своих отчётов на “базу”, один отчёт перегонял больше часа), и как в нём не работают некоторые фичи, которые вполне хорошо работали в “бете”. И про то, что мои попытки переключиться на x64-вариант закончились, можно сказать, ничем (хоть и работает он не в пример стабильнее – точнее, вовсе ни разу не завалился, и фичи в нём все работают, и быстрее он – по ощущениям, конечно).

Остановило и заставило вернуться к 86-варианту IE9RC, наряду с невозможностью сделать x64-вариант браузером по умолчанию,  отсутствие в природе x64-варианта одной “флагманской” вещи – Silverlight’а. Вот Adobe свой x64 Flash-плеер выпустила, ролики в x64-IE смотреть можно запросто, а MSFT конкурирующий SL – не выпускает (и даже анонсов не припоминается). А так как довольно много приходится заниматься Шарепойнтом, в котором заметная часть интерфейса переведена на Silverlight, - приходится постоянно спотыкаться: привыкаешь к новому…

В связи с этим вспомнился прошлогодний скандал после обмолвки одного из руководителей MSFT про скорый конец Silverlight’а – очень быстро для успокоения возмущённой общественности “анонсировали” пятую “версию” SL, на чём общественность и успокоилась… Получается, что зря успокоилась – забросят, всё же, Silverlight… Вероятность того, что забросят x64 линейку продуктов, следует оценивать, по-моему, гораздо ниже…

А жаль – работать с SL гораздо продуктивнее (в разных смыслах), чем с jscript. Остаётся надеяться, что сработает традиция MSFT поддерживать всякие legacy и истреблять уже имеющийся SL не станут.



среда, марта 02, 2011

Сапоги от пирожника

Порекламировали тут  в рассылке Google Cloud Connect

 

Поставил это чудо, покрутил, но так и не понял особого смысла всей затеи. Ну да,  закинул документ Ворда в Google Docs - там его можно открыть в браузере и посмотреть. При редактировании, что в браузере, что в Ворде на десктопе, порождаются отдельные версии документа и не предлагается никаких средств для слияния Раздраженный  Хотя есть share - можно пригласить людей для как бы совместной работы над документом.

Excel и вовсе повисла на "подготовке к синхронизации".

 

Office Web Apps ведут себя не в пример лучше - документ редактируется, предлагается режим одновременного редактирования, а потом версии сливаются, браузерная и десктопная.

 

В итоге снёс примочку, тем более, что она присобачила  собственную дополнительную панель жуткого вида и нехилых размеров. Ленту, похоже, не осилили...

 

Technorati Tags: ,


воскресенье, февраля 20, 2011

Дожили…

Работать с Шарепойнтом в ряде случаев уже удобнее с использованием браузеров Google Chrome или Mozilla Firefox.

Один из таких случаев – групповая загрузка файлов в библиотеку.

В принципе, Шарепойнт предлагает “встроенную” функциональность в виде кнопки “Отправить несколько документов” на ленте

image

Однако эта кнопка работает только в случае, если на компьютере пользователя установлен MS Office 2007/2010 (да и то не всегда – я на собственной машине правильной работы компонента добиться не могу, списываю на то, что кроме Офиса много всего понапичкано…). Но если работает, то всё работает хорошо – выбирать файлы достаточно удобно, обработчики, установленные в библиотеке, правильно обрабатывают загружаемые файлы.

Второй “стандартный” способ – с использованием WebDAV (через “представление проводника”)

image

Выбирать файлы достаточно удобно, однако с копированием могут быть проблемы -

image

Копирование происходит очень медленно, а обработчики обрабатывают файлы не совсем верно (похоже, при этом, как и при добавлении файлов вручную, по одному, выполняется “двухтактная” работа: сначала добавление файла в папку, потом редактирование элемента списка для установки атрибутов). В результате правильно срабатывает обработчик ItemAdded, а обработчик ItemUpdated запускается впустую (нужных атрибутов никто ведь не устанавливает…). С другой стороны, если никаких обработчиков нет, то и такой способ может пригодиться.

Для использования с другими браузерами на Codeplex можно найти симпатичный компонент Drag & Drop upload for SharePoint, который устанавливается на ферму и даёт возможность загружать файлы в библиотеки перетаскиванием из окна проводника Windows:

image

Выбирать файлы для загрузки достаточно удобно, обработчики, установленные в библиотеке, правильно обрабатывают загружаемые файлы

Итого: Наиболее удобным (когда работает) для использования следует считать “встроенный” способ с использованием офисных компонентов, наиболее надёжным и дешёвым – способ с использованием браузера Google Chrome и решения RENIT DragNDropUpload SP2010.

Technorati Tags: ,


вторник, февраля 08, 2011

Споткнуться на ровном месте - 4

Очередной капкан обнаружился опять при работе с новым типом (ContentType) “набор документов” (DocumentSet). Потребовалось в качестве свойств элемента этого типа использовать Lookup-поля, ссылающиеся на списки в узлах, отличных от того, на котором лежит библиотека с нашими элементами…

Всё шло хорошо до того момента, когда значения Lookup-свойств потребовалось вывести на странице набора. Значения не выводились! WTF… Схожу с ума от злости

Раскопки с помощью Reflector’а показали, что веб-часть DocumentSetPropertiesWebPart (используется для вывода свойств набора) использует для рендеринга метод SPField.GetFieldValueAsHtml(), который для Lookup-полей, работающих со списками с других узлов, выводит пустую строку Удар. Собственно, разработчик этого метода, похоже, не подозревал о способностях поля работать с “посторонними” списками, поэтому и не использовал параметр LookupWebId Даже не знаю, а по-простому обращался к списку со “своего” узла. Нормальненько так… Черный баран

Для обхода капкана можно, конечно, написать свою веб-часть вместо DocumentSetPropertiesWebPart, однако выяснилось, что так же ведёт себя и DocumentSetContentsWebPart, отображающая список документов внутри набора. А писать собственные гриды – удовольствие тО ещё…

В общем, спасибо индийским коллегам…

Technorati Tags:


четверг, января 20, 2011

Сюрприз от DocumentSet - 2

Второй сюрприз от неплохого типа – неверный перенос средствами экспорта/импорта настроек представления для содержимого набора документов. После импорта используется представление по умолчанию для библиотеки, а вовсе не то представление, которое было настроено до экспорта.

Исправляются последствия сюрприза использованием вот такого метода:

   1: /// <summary>
2: /// Востановление представления стартовой страницы набора документов
3: /// </summary>
4: /// <param name="list">список/библиотека</param>
5: /// <param name="contentTypeName">Название типа содержимого</param>
6: /// <param name="viewName">имя представления</param>
7: private void ResetDocSetView(SPList list, string contentTypeName, string viewName) {
8: SPContentType contentType = null;
9: try { contentType = list.ContentTypes[contentTypeName]; } catch { }
10: if (contentType != null) {
11: DocumentSetTemplate docSetTemplate = DocumentSetTemplate.GetDocumentSetTemplate(contentType);
  12:         if ((docSetTemplate.WelcomePageView == null)  (docSetTemplate.WelcomePageView.Title != viewName)) {
  13:             SPView view = list.Views.TryGetView(viewName);    
  14:             if (view != null) {
  15:              docSetTemplate.WelcomePageView = view;  
  16:                 docSetTemplate.Update(true);    
  17:             } else {    
  18:                 msgError +=     
  19:                     string.Format("В списке [{1}] отсутствует представление [{0}]", viewName, list.Title);    
  20:             }    
  21:         }    
  22:     } else {    
  23:         msgError +=    
  24:             string.Format("В списке [{1}] отсутствует тип [{0}]", contentTypeName, list.Title);    
  25:     }    
  26: }
Technorati Tags: ,


пятница, декабря 31, 2010

Нда…

Как-то WordPress не торопится подтверждать мнение, что он лучший “движок” для блогов. Blogspot покруче будет – больше всякого правильно отображает…

Да, а “нравится” для мордокниги ни там, ни тут не отображаются, Tweet Meme – только на Blogspot. Тщательнее надо, тщательнее…



Тестирую новые плагины для Writer

Ну, для меня новые – давно не копался в этой галерее…

Now Playing – не фурычит, ни на WMP? ни на Foobar2000 Тошнит Палец вниз

Picasa 

   фурычит… Палец вверх

CodeFormatter Дай пять!

код текстом:

SP.Ribbon.PageState.PageStateHandler.prototype = {

getFocusedCommands:
function() {ULSMg8:;
return null;
},





код картинкой:





четверг, декабря 30, 2010

Сюрприз от DocumentSet

В неплохом типе (ContentType) “Набор документов” (DocumentSet) обнаруживается плохо замаскированная бомбочка замедленного действия (скорее, даже, забытый разработчиками мешок с мусором – как иногда хирурги забывают ножницы в животе пациента…).
В этом мешке валяются обращения к неведомым обработчикам событий этого типа данных. В обычных обстоятельствах эти вызовы ничем себя не обнаруживают, активизируются они при подключении других обработчиков (например, вот этого) и проявляются в виде замусоривания системного лога сообщениями вида:

Ошибка при загрузке и запуске приемника событий Microsoft.Office.DocumentManagement.DocumentSets.DocumentSetEventReceiver в Microsoft.Office.DocumentManagement, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c.
: В экземпляре объекта не задана ссылка на объект.

Поиск показывает, что сюрприз известен уже давно и благополучно пережил несколько “кумулятивных обновлений” Sharepoint 2010.
Лечится выбрасыванием мешка на помойку - удалением этих “обработчиков” (DocumentSetItemsEventReceiver и DocumentSetEventReceiver) из всех библиотек, использующих тип DocumentSet.
Technorati Tags:

Оказывается - 7

Для поля типа SPFieldUrl практически нельзя задать значение по умолчанию. Собственно, задать можно, но только в формате “<url>” – в этом случае поле в новом элементе получает формально правильное значение “<url>, <url>”, что эстетически как-то не очень…

Задание значения по умолчанию "в “эстетичном” формате “<url>, <title>” приводит к значению поля вида “<url>,, <title>, <url>, <title>”, что неверно не только эстетически, но и по сути – ссылка получается кривая.

Вот такой вот сюрприз…

Technorati Tags:

вторник, ноября 30, 2010

Значение ID из УРЛ страницы

В коде веб-части для получения значения параметра ID (да и любого другого) из УРЛа страницы, на которой веб-часть установлена, можно использовать LINQ-выражение:

   1: ID = (from urlParameterName in this.Page.Request.QueryString.AllKeys 
   2:       where urlParameterName.ToUpper() == "ID"
   3:       select this.Page.Request.QueryString[urlParameterName]).FirstOrDefault();

Выглядит забавно, написать сразу не получается (не то, что кучка циклов из MSDN), но преимуществ такого подхода много…

понедельник, ноября 29, 2010

Оказывается - 6

Свойства узла (SPWeb.Properties) являются “неистребимыми” – их можно добавлять, их значения можно менять, но их нельзя удалить. Формально, конечно, метод .Remove() существует и даже как бы действует, но при обновлении значения узла все свойства оказываются на месте. Можно действовать средствами PowerShell, можно средствами ОМ в программе на C# – эффект одинаков. Разница в том, что в C# можно установить значение в null, в PS присваивание $null присваивает пустую строку.

Вот такой маленький сюрпризик Дразнюсь.

Technorati Tags:

среда, ноября 17, 2010

Оказывается - 5

… что и MSDN не всегда говорит правду.

Например, читаем

An expression using the &= assignment operator, such as

x &= y

is equivalent to

x = x & y 

На практике оказывается, что эквивалентность для логических операндов наблюдается только в приведённом примере:

class AndAssignment
{
static void Main()
{
bool b = true;
b &= false;
Console.WriteLine(b);
}
}
/*
Output:
False
*/

Если же операнд y является вызовом какой-либо процедуры, то оператор &= эту процедуру вызывает всегда, независимо от значения x.

суббота, октября 30, 2010

Октябрьский CU

Установил неслабого такого размера (ок. 150 Мб) набор апдейтов для OSS 2010 422859_intl_x64_zip.exe и выяснил, что почитали MSDN!!! Пламенный приветСолнце