суббота, февраля 28, 2009

PS и WSS 3

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

   1:  function ApproveItemContent {
2: if (-not $list.EnableModeration ){ return; }
3: if ($item.ModerationInformation.Status –eq
Microsoft.SharePoint.SPModerationStatusType]::Approved `
4: -or `
5: $item.ModerationInformation.Status –eq
Microsoft.SharePoint.SPModerationStatusType]::Denied)
6: { return; }
7: $this.DisableEventFiring()
8: try{
9: $item.ModerationInformation.Status = `
10: [Microsoft.SharePoint.SPModerationStatusType]::Approved;
11: $item.ModerationInformation.Comment = 'Approved with PS-script by user '
12: + $user.Name + ' at ' + [System.DateTime]::Now.ToString();
13: $item.SystemUpdate();
14: }catch{
15: # не очень и хотелось...
16: }
17: }

Эту функцию записываем в конец заготовки обработчика и ставим её вызов в обработчики добавления и обновления:


function ItemAdded{ ApproveItemContent; }
function ItemUpdated{ ApproveItemContent; }
Не обошлось, как водится, без сюрпризовsmile_nerd: на списке вики-страниц ( узел создавался с шаблоном “вики”) скрипт работает наполовину – комментарий (строка 11) записывается, а статус (строка 9) – нет. При расследовании выяснилось, что исправляет дело замена SystemUpdate() на Update() в строке 13.

Technorati Tags: ,

пятница, февраля 27, 2009

PS и WSS 2

Во второй серии балета экспериментов пытаемся сделать при помощи PS-технологии нечто содержательное. Например, достаточно часто требуется для элементов списка (документов библиотеки) оставить доступ только создателю и некоторым группам пользователей, отобрав его у всех остальных. Достаточно легко эта операция проделывается при помощи рабочего процесса с использованием activities из пакета Useful Sharepoint Designer Custom Workflow Activities. Алгоритм достаточно простой:

  1. Убрать наследование разрешений
  2. Установить разрешения для групп
  3. Установить разрешения для создателя.

Для использования в обработчике событий PowerEventReceivers имеет смысл написать функцию, выполняющую нужные действия, и вызывать её из обработчиков ItemAdded и ItemUpdated. Функция получается такая:

function ResetPermissions{
$groupsNames = "Администрация", "ИТ Отдел";
$permissionLevelName = "Полный доступ";
$permissionLevel = $null;
$mustSave=$false;
if( -not $item.HasUniqueRoleAssignments){
try{ $item.BreakRoleInheritance($false); }
catch{
# у пользователя нет нужных разрешений
return;
}
}
if($item.HasUniqueRoleAssignments){
try{
$permissionLevel = $web.RoleDefinitions[$permissionLevelName];
}catch{
# у пользователя нет разрешений или неверно задан уровень
}
if($permissionLevel -ne $null){
try{
foreach ($groupName in $groupsNames) {
$group = $null;
try{$group = $web.Groups[$groupName];}catch{} #on web
if($group -eq $null) {try{$group = $web.Site.Rootweb.Groups[$groupName];}catch{}} #on site
if($group -eq $null) {continue;} #wrong group
$role = New-Object -TypeName Microsoft.SharePoint.SPRoleAssignment -ArgumentList $group;
$role.RoleDefinitionBindings.Add($permissionLevel);
$item.RoleAssignments.Add($role);
$mustSave=$true;
}
}catch{
if(-not $mustSave){
return;
}
}
#Creator
try{
$user = (($item.Fields[[Microsoft.SharePoint.SPBuiltInFieldId]::Author] `
-as [Microsoft.SharePoint.SPFieldUser]).GetFieldValue($item[[Microsoft.SharePoint.SPBuiltInFieldId]::Author].ToString()) `
-as [Microsoft.SharePoint.SPFieldUserValue]).User;
$userRole = New-Object -TypeName Microsoft.SharePoint.SPRoleAssignment -ArgumentList $user; #SPRoleAssignment
$userRole.RoleDefinitionBindings.Add($permissionLevel);
$item.RoleAssignments.Add($userRole);
$mustSave=$true;
}catch{
if(-not $mustSave){
return;
}
}
}
if($mustSave){ # сохранить изменения
$item.SystemUpdate();
}
}
## End of ResetPermissions ##
}

Такая функция исполняется ожидаемым образом только когда изменения списка проводит пользователь, имеющий права на изменение разрешений. У пользователя, не имеющего таких прав, дело заканчивается неудачей и разрешения на элемент списка наследуются от списка. Внутри скрипта дело поправить не удаётся (нужно выполнить код с системными привилегиями), поэтому следует искать другие выходы.

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

Из “других” средств можно применить SharePoint Designer PowerActivity того же автора. В рабочем процессе, основанном на этой “активности”, можно применить тот же самый скрипт, что и в обработчике событий. С учётом того, что рабочие процессы выполняются в контексте системной учётной записи, изменения проходят у любого пользователя, имеющего разрешения на добавление и/или редактирование элементов списков. Платой за это служит необходимость иметь SPD.

Тексты скриптов для обработчика (RecieverScript.ps1) и для PowerActivity (WFScript.ps1) можно взять здесь.


Technorati Tags: ,

вторник, февраля 24, 2009

PS и WSS

В то время как по всей России страдают многие энтузиасты ратуют за использование PowerShell в деле борьбы работы с Шарепойнтом, как-то у меня самого дальше советов пользователям форума пока не продвинулось. smile_embaressed Надо восполнить пробел…

Первая серия экспериментов – с обработчиком событий iLoveSharePoint.PowerEventReceivers, представленным Christian’ом Glessner’ом (http://www.iLoveSharePoint.com). Задача – попробовать, легко ли писать скрипты для этого обработчика и как эти скрипты должны выглядеть. Содержательно – скрипты должны добавлять свои сообщения в предназначенное для этого поле.

Результат: скрипты писать легко и просто, совсем как в Студии на C#, но можно и не обращать внимания на регистр символов (спасибо MS за любовь к BASIC’у). Вид же скриптов сильно зависит от типа обработчика (вызов перед началом события/после события). Гугль подсказывает, что народ с этим постоянно сталкивается и пытается бороться. Поэтому просто примем это за реальность и правила будем использовать такие:

  • в методах, вызываемых перед началом события (ItemAdding, ItemUpdating и т.п.) работаем с After-свойствами:
    function ItemAdding{
    $message="Adding;"; $fieldName="msg";
    $internalFieldName=$list.Fields[$fieldName].InternalName;
    $properties.AfterProperties[$internalFieldName]+=$message;
    }

  • В методах, вызываемых после события (ItemAdded, ItemUpdated и т.п.) работаем с полями элемента списка:
    function ItemAdded{
    $message="Added;"; $fieldName="msg";
    $internalFieldName=$list.Fields[$fieldName].InternalName;
    $item[$internalFieldName]+=$message;
    $item.SystemUpdate();
    }

Technorati Tags: ,

вторник, февраля 03, 2009

Something strange …

That day, trying to unravel the mystery of (ideally, to find workaround) on the lack of access to data on Sharepoint sites with anonymous access allowed (!?).

Here is a test console program:

using System;
using GetListDataWCF.Lists_WS; // proxy for Lists.asmx
using System.Net;
using System.Xml;

namespace GetListDataWCF {
class Program {
static void Main(string[] args) {
if (args.Length > 0)
new Test().GetData(args[0]);
else
Console.WriteLine(
"Usage:{0} <url of site>",
typeof(Test).Assembly.ManifestModule.Name);
}
}
class Test {
public void GetData(string url) {
Lists lists = new Lists();
lists.Url = url.TrimEnd("/".ToCharArray()) +
"/_vti_bin/Lists.asmx";
lists.Credentials = CredentialCache.DefaultCredentials;
XmlNode tst =null;
try {
tst = lists.GetListCollection();
Console.WriteLine(string.Format(
"success: {0} bytes", tst.OuterXml.Length));
} catch (Exception err) {
Console.WriteLine(
string.Format("error: {0}", err.Message));
}
}
}
}
The program applies to the site, the URL of which passed through the command-line switch causes the method GetListCollection () of Lists.asmx service, and if successful, displays the size of the response service (the contents of the response in this case does not matter). . Compiled software - are here. Actually, the algorithm taken from SDK, I have used it in various programs and until recently (at least until September-October 2008) was carried out successfully to all nodes, which allow anonymous access to the data.

Now, the bizarre result of the program depends on the user launching the program, and maybe even from some factors. Most often, the result is "error: The request failed with HTTP status 401: Unauthorized.", in the case of Forms-authentication - "403, forbidden". Cases of successful fulfillment of requests are rare. smile_omg In doing so, such conduct "different" only WSS-3 sites, sites WSS-2 give the data as expected.

To check you can use nodes with addresses
http://sharepoint-community.ru:55555/ (Win-authentication)
http://sharepoint-community.ru/ (Forms-authentication)
http://www.sharepointcommunity.com/ (Win-authentication)
http://new.hse.ru/sites/ibs_test/ (WSS-2 site).
At all sites allow anonymous access to the data, the successful completion of the testing program is observed only at the last node. smile_eyeroll

Very similar to the result of "improvements" in security ... thumbs_down

Technorati Tags:

вторник, января 20, 2009

Что-то странное…

Который день пытаюсь разгадать загадку (в идеале, найти пути обхода) по отсутствию доступа к данным на Шарепойнт-узлах с разрешённым анонимным доступом (!?).

Вот тестовая консольная программка:

using System;
using GetListDataWCF.Lists_WS; // proxy for Lists.asmx
using System.Net;
using System.Xml;

namespace GetListDataWCF {
class Program {
static void Main(string[] args) {
if (args.Length > 0)
new Test().GetData(args[0]);
else
Console.WriteLine(
"Usage:{0} <url of site>",
typeof(Test).Assembly.ManifestModule.Name);
}
}
class Test {
public void GetData(string url) {
Lists lists = new Lists();
lists.Url = url.TrimEnd("/".ToCharArray()) +
"/_vti_bin/Lists.asmx";
lists.Credentials = CredentialCache.DefaultCredentials;
XmlNode tst =null;
try {
tst = lists.GetListCollection();
Console.WriteLine(string.Format(
"success: {0} bytes", tst.OuterXml.Length));
} catch (Exception err) {
Console.WriteLine(
string.Format("error: {0}", err.Message));
}
}
}
}
Программа обращается в узлу, УРЛ которого передан через параметр командной строки, вызывает метод GetListCollection() сервиса Lists.asmx и в случае успеха выводит размер ответа сервиса (содержимое ответа в данном случае неважно). Скомпилированная программа – здесь. Собственно, сам алгоритм из SDK, используется у меня (с вариациями) в разных программах и до недавнего времени (по крайней мере, до сентября-октября 2008 г.) выполнялся успешно для всех узлов, на которых разрешён анонимный доступ к данным.
Сейчас же результат работы программы причудливым образом зависит от пользователя, запустившего программу, и, может быть, ещё от каких-то факторов. Чаще всего результатом бывает “error: Сбой запроса с состоянием HTTP 401: Unauthorized.”, в случае Forms-аутентификации - “403, forbidden”. Случаи успешного выполнения запросов редки. smile_omg При этом таким поведением “отличаются” только сайты WSS-3, сайты WSS-2 отдают данные, как и ожидается.
Для проверки можно использовать узлы с адресами
http://sharepoint-community.ru:55555/ (Win-аутентификация),
http://sharepoint-community.ru/ (Forms-аутентификация),
http://www.sharepointcommunity.com/ (Win-аутентификация),
http://new.hse.ru/sites/ibs_test/ (версия WSS-2).
На всех узлах разрешён анонимный доступ к данным, успешное выполнение тестовой программы наблюдается только на последнем узле.smile_eyeroll

Сильно похоже на результат “усовершенствования” в деле безопасности… thumbs_down


Technorati Tags:

пятница, декабря 26, 2008

База знаний на шаблоне "Блог", continued

Начало истории – здесь, ответвление на расследования – здесь. На небольшие дополнительные усовершенствования навела статья в блоге Артёма Проничкина и отысканная при помощи Google статья о добавлении нескольких категорий к постам блогов.

Собственно, все рекомендации (c необходимыми адаптациями к окружающей среде) были применены и теперь блок “Статьи” функционирует на доступном народу сайте.

Technorati Tags: ,

среда, декабря 24, 2008

Блог-засада, continued

Начало истории – здесь. Продолжение последовало довольно скоро – при переносе модифицированного блога на другой сайт. Естественным образом (впитанным с древних времён предыдущих версий WSS) перенос был выполнен через шаблон узла с сохранением содержимого. На целевом сайте по шаблону получился вполне рабочий сайт, база начала наполняться. Засада обнаружилась при попытке добавить комментарии к статье: формы для нового комментария на странице не было.smile_angry 

Расследования показали, что на странице отсутствует веб-часть ListFormWebPart с названием “New Comment”, которая имеется на узле блогов, созданных обычным порядком. Похоже, модуль создания узлов по пользовательским шаблонам не смог правильно присвоить значения свойствам этой веб-части и попросту её проигнорировал. smile_omg Вылечить недуг удалось при помощи Sharepoint Designer’а: со страницы Post.aspx нормального блога скопирован текст искомой веб-части, вставлен в соответствующую дефектную страницу и исправлено значение свойства ListName (его правильное значение можно взять в одноименном свойстве веб-части “Заметки, комментарии”, после которой, собственно, и следует вставлять “New Comment”). После такого лечения появилась возможность запостить комментарии к статьям.smile_nerd

Для уменьшения количества и трудоёмкости лечебных процедур можно использовать импорт командой
STSADM.EXE -o import -url <new-url> -filename articles.impex.
Команда не выбрасывает из страницы помянутую веб-часть, но и не исправляет значения свойства ListName, в результате чего при открытии страницы система радостно рапортует о наличии ошибок и невозможности показать что-либо изумлённой публике. Лечится также при помощи Sharepoint Designer’а: открыть дефектную страницу Post.aspx и исправить значение свойства ListName.smile_secret

Желающие поупражняться в лечении могут взять файл для импорта articles.impex здесь soccerball, файл шаблона articles.stp – здесь turtle.

Technorati Tags: ,

понедельник, декабря 22, 2008

LiveID Authentication - практика

После некоторого времени эксплуатации LiveID Authentication на сайте Российского сообщества Sharepoint начали выявляться недостатки этого способа.smile_omg

Никакие программы, включая недавно выпущенную Windows Live Writer, не подозревают о существовании такого способа аутентификации. В результате на узлах/страницах невозможно использовать клиентские программы (а основном, это программы MS Office – Word, Excel), даже при включении в “админке” интеграции клиентов (в этом случае при помощи клиента забрать, например, документ из библиотеки на редактирование можно, но вернуть отредактированный документ – только через сохранение на локальном диске и загрузку оттуда в библиотеку). Невозможно также подключать списки к Outlook, редактировать узлы и страницы при помощи Sharepoint Designer и постить в блоги при помощи Live Writer.smile_cry

Для обеспечения “пропавших” возможностей приходится делать доступным внешним пользователям вход на сайт, на котором настроен метод Windows-аутентификации (или работать в консоли сервера через RDP). smile_wink

Частично проблемы решаются (например, с Outlook и Sharepoint Designer) связыванием на IIS сервера сайта с Windows-аутентификацией с протоколом https.

Такая несогласованность продуктов не мешает, однако, важной функции рассылки оповещений. Для этого необходимо только правильно указать e-mail пользователя в анкете "Мои настройки LiveID". clap

пятница, декабря 12, 2008

Windows Live и реклама

Много и упорно работают люди над сервисами Windows Live, за что им спасибо hug_dude. Однако с рекламой явно переборщили – понатыкали жутковатых баннеров, в итоге всё моргает и моего 19” монитора маловато. А что делается на 15” – представить страшно. Пришлось написать скрипты для надстройки IEPro, которые эти баннеры скрывают. Сама надстройка – здесь, скрипты – здесь.

Эти же скрипты годятся для использования в Firefox v.3 с установленным дополнением Greasymonkey.

Technorati Tags: ,

четверг, декабря 11, 2008

Снова засада

Всем почти хорошая штука LiveID authentication, но вот не желают с ней работать разные программы – ни документы из библиотеки не открываются, ни страницы при помощи Sharepoint Designer не поредактировать smile_omg.

Дело с открытием документов решается включением “интеграции клиентов” на странице “Изменение параметров проверки подлинности “ в “Центре администрирования” (по умолчанию интеграция отключена с предупреждением типа “не все клиенты совместимы с проверкой на основе форм” и соответствующих пунктов в меню библиотек и страниц даже и не появляется). Но решается только наполовину – извлечь документ приложением можно можно, но положить после редактирования обратно приложение уже не может. Только через сохранение файла на локальном диске и загрузку его в библиотеку.smile_confused

С редактированием же страниц при помощи SPD – не решается никак smile_angry. Только через расширение приложения, которое имеет Windows Authentication.

Technorati Tags: ,

четверг, ноября 27, 2008

Локализация Windows Live Authentication (continued)

После некоторых упражнений с Sharepoint (по-правде, в упражнения входил полный снос и повторная установка) обнаружился ещё один недостаток - пропала группа Authenticated Live Users (аналог группы NT AUTHORITY\authenticated users для Windows-аутентификации). Понятно, что она должна создаваться провайдером, но когда и как его подтолкнуть на этот подвиг, выяснить не удалось. А без такой группы настраивать разрешения для каждого пользователя – ужасная затея…

В итоге добавил процедуру формирования на каждом узле, где предполагается использование LiveID-аутентификации, группы с именем вида <имя узла> - Authenticated Live Users. При логине или изменении данных пользователи заносятся в эту группу.

Для облегчения жизни добавил скрипт _config.cmd с инструкцией по настройке в файле README_ru.txt.

Результаты можно скачать отсюда (установочный пакет) и отсюда (целиком проект с исходными текстами).


Technorati Tags: , ,

среда, ноября 12, 2008

Локализация Windows Live Authentication

На codeplex Lawrence Liu размещено отличное решение по аутентификации на Sharepoint-сайтах с использованием Windows LiveID. Практически готовое к использованию решение и, если не обращать внимание на мелкие неудобства, его можно сразу и использовать.

Неудобства заключаются, во-первых, в неправильной работе редактора профиля LiveID, подключённого через CustomAction к меню пользователя (введённые данные не передаются в свойства пользователя узла и после закрытия редактора пользователь оказывается в корневом узле). Во-вторых, решение явно разработано без учёта использования на системах с неанглийской локализацией (все формы/меню на английском, а использовать узел с русской, например, локализацией в качестве служебного, просто не получается).

Для исправления недостатков проведён анализ предоставляемого кода и исправлены досадные ошибки (неверная привязка EventHandler’а, к примеру). Жёсткая привязка к английской локализации устранена заменой в двух операторах

SPListTemplate template = web.ListTemplates["Custom List"];
SPList list = sweb.Lists["User Information List"];

использования английских имён списков и шаблонов на вызовы методов, не зависящих от локализации. Кроме того, заменено использование list.Fields["Title"] на list.Fields[SPBuiltInFieldId.Title]. В результате решение стало работать и на узлах с русской локализацией.

Перенаправление на корневой узел исправлено добавлением адреса контекстного узла в описание CustomAction:

<UrlAction Url="~site/_layouts/liveinfo.aspx"/>

Средства для локализации решения обнаружились в блогах Mikhail Dikov, Maxime Bombardier и Jan Tielens. В aspx-формах и XML-описаниях текстовые константы заменены ссылками на строки в ресурсном файле LiveIDAuth.<culture>.resx. Нетривиальным, как выяснилось, является размещение ресурсов для использования в разных объектах. Так, для Feature-объектов, размещённых в папке \12\TEMPLATE\FEATURES\WindowsLiveAuthenticationSettings, ресурс должен находиться в папке \12\Resources (с использованием ссылок вида $Resources:LiveIDAuth,varName) или в папке 12\TEMPLATE\FEATURES\WindowsLiveAuthenticationSettings\Resources\ с именем Resources.<culture>.resx (с использованием ссылок вида $Resources:varName).

Для aspx-форм ресурс должен находиться в папке App_GlobalResources web-приложения.

В итоге в wsp-пакет пакет помещаются две копии ресурса с разными именами в разные папки (WindowsLiveAuthenticationSettings\Resources\Resources.resx и Config\Resources\LiveIDAuth.resx), а командный файл для установки дополнен командой
stsadm -o CopyAppBinContent,
копирующей ресурсы в папки App_GlobalResources веб-приложений.

Продолжение истории - здесь.

Результаты можно скачать отсюда (установочный пакет) и отсюда (целиком проект с исходными текстами).

Technorati Tags: , ,

воскресенье, ноября 02, 2008

База знаний на шаблоне "Блог"

Пытался на базе шаблона “блог” сделать узел для работы со статьями. Статьи от “записей” блога отличаются довольно мало, поэтому была надежда малыми силами (средствами WSS и, м.б., SPD) привести узел к нужному состоянию.smile_thinking

Добавил к списку "Записи"(Posts) поле "Автор статьи", изменил параметры веб-частей (поля запроса, группировка, сортировка) на страницах default.aspx и Post.aspx. Всё легко прошло, не удалось только сделать нормальную группировку по авторам (группировка-то получилась, но на страницу при этом мимо всяких веб-частей и зон лепится текст, до управления выводом которого простыми средствами добраться не удалосьthumbs_down). Пришлось ограничиться сортировкой по автору и названию, что, впрочем, и не так уж и плохо.

Засада ждала на странице Category.aspx, показывающей список с фильтром по категориям. Очень быстро выяснилось, что страница очень легко портится простым изменением состава полей запроса данных – после этого не показывается никаких результатов (или все сразу, в зависимости от настроек фильтра в запросе). При этом выяснилось, что инвалидность страницы – 1-й степени (работоспособность не восстанавливается никакими доступными средствами). Попутно обнаружилось, что стандартные средства связи веб-частей не используются, а сама фильтрация закопана где-то в коде.smile_angry

В итоге ничего не оставалось кроме действий по учебнику – связал две веб-части стандартным способом и всё заработало.smile_nerd Внешний вид, конечно, похуже… Но в итоге даже SPD не понадобился.

Technorati Tags: ,

четверг, октября 30, 2008

Sharepoint, Outlook и Windows Mobile

Навели (заказчик, кстатиsmile_wink) на мысль использовать сабжевую комбинацию для документирования взаимодействия (получение заданий, отчёт о выполнении) с заказчиками - одним или несколькими, связанными или независимыми. Сделать оказалось довольно просто.

Настройка системы:

  1. На узле у заказчика (личном узле работника или ещё каком...) создаётся список типа "Задачи" с именем, например, "Задачи для Иванова И.И."
  2. Там же создаётся список типа "Календарь" с именем "Выполнение заданий Ивановым И.И."
  3. Оба списка подключаются к Outlook (Действия -> Подключиться к Outlook), при подключении папкам даются имена "Задания от ХХХ" и "Выполнение заданий ХХХ" соответственно.
  4. На мобильное устройство под Windows Mobile v.5+ (смартфон, PPC) устанавливается , настраивается синхронизация задач и календаря устройства с настольным компьютером.

П.п. 1-3 выполняются по всем работодателям.

Методика работы:

  • Те задания из папки "Задания от ХХХ", выполнение которых требуется трассировать, переносятся (правой кнопкой мышки, скопировать) в основной список задач Outlook, с которым выполняется синхронизация для мобильного устройства.
  • При выполнении задания запускаем на устройстве трассировку задачи, после окончания останавливаем и сохраняем результат в календаре устройства.
  • После синхронизации с настольным компьютером результаты трассировки (помечены категорией "[tracking report]") переносим в соответствующую папку "Выполнение заданий ХХХ".

В результате заказчик выдаёт задания и контролирует ход их выполнения через интерфейс своего Sharepoint-узла, а работник взаимодействует с Outlook'ом и своим мобильным устройством. При отсутствии мобильного устройства трассировку, собственно, можно делать и "вручную" внесением записей в календарь "Выполнение заданий ХХХ".

Примечание. Задачи должны иметь непустые поля дат начала и окончания, в противном случае синхронизация с устройством не проходит (по крайней мере, так у меня на Vista sp1, Outlook 2007 и qtek 3810 с WM5)

среда, октября 01, 2008

Punto switcher v.3

Попробовал новую версию программки. Работает, вроде, но в IE8 beta2 – облом.

Переключение раскладки доп.клавишами - не фурычит. Даже индикация раскладки в трее не работает. Говорить про автоматическое переключение даже и на стоит. Только полуавтомат (выделить и Shift-Break). smile_omg

Выяснилось, что из всякой задницы можно найти выход - отключил UAC, всё стало работать как надо.clap

IE8 beta2 и Google

Дерутся две компании - ничего из гуглевского в ИЕ8 b2 толком не работает - ни почта, ни блоги.
Кто уж там больше выпендривается - ХЗ. Похоже, Гугль - вчера вполне в блоги заметки писались, сегодня фокус не удаётся: при открытии редактора браузер входит в цикл с открытием новых вкладок и окон. Смотрится смешно.thumbs_up

После проведения разысканий, выяснилось, что и Microsoft не плошает - на ИЕ7 происходят те же фокусыclap. И не только на гуглевских сервисах, но и на Hotmail.com тоже. Кроме того, вспомнилось, что в очередной раз включил “на попробовать” UAC. После отключения этого чуда всё прошло. В общем, попробовал… smile_angry

четверг, сентября 18, 2008

Новый Writer

Предложили скачать, скачал, вот пишу в нём. smile_speedy

Ничего плохогоrose, и картинки просто вставлять стало. Может, ещё чего хорошего найдётся.smile_embaressed

Technorati Tags:

вторник, сентября 02, 2008

psiCards-KB - формулы

Вот примеры, которые можно использовать в вычисляемых полях.

1. Перевод первого символа в верхний регистр:

Строка:= xs="#this#", 
String.IsNullOrEmpty(xs)?"":
xs=xs.Trim(), String.IsNullOrEmpty(xs)?"":
xs.Length==1?xs.ToUpper():
xs.Substring(0,1).ToUpper()+xs.Substring(1)

2. Проверка возраста на заданное число лет:

Строка:=xi=16,xs="~~Дата рождения~~",xs==""?"": 
(new DateTime(
Int32.Parse(xs.Split('.')[2]),
Int32.Parse(xs.Split('.')[1]),
Int32.Parse(xs.Split('.')[0])) > DateTime.Today.AddYears(-xi))?
throwerr(String.Format("Возраст не может быть меньше {0} лет!",xi)):xs
/*годится для русской локализации */

3. Проверка даты на заданное "упреждение" - время от текщего момента до срока в дате:

Строка:=DateTime.Parse("#this#")>DateTime.Now.AddHours(24)?"#this#":
throwerr("Заявка не может быть оформлена позднее, чем за 24 часа до начала конференции")

вторник, августа 19, 2008

Опять сюрприз...

Попытался использовать в форме стандартный контрол UserField. Нашлась неплохая статеечка на эту тему. Добавил код, как описано, плюс после некоторых поисков добавил ещё контекст (по умолчанию контрол работает на том же узле, что и связанный список), т.к. мне нужно работать со списками с других узлов. В общем, всё замечательно, только кнопка для выбора пользователей никакого эффекта не вызывает.smile_embaressed Кнопка проверки ввода работает, а эта - нет.smile_angry При внимательном рассмотрении выяснилось, что не находится имя нужной функции, причём по причине длины имени!? В итоге получился вот такой работающий фрагмент кода thumbs_up:

((UserField)ValElem).ListId = DataItem.ListItems.List.ID;
((UserField)ValElem).ItemId = DataItem.ID;
((UserField)ValElem).ID = "uf_" + DataItem.Fields[name].Id.ToString("N");
//DataItem.Fields[name].Id даёт слишком длинное имя!!!smile_omg
((UserField)ValElem).FieldName = this.Name;
((UserField)ValElem).ControlMode = SPControlMode.Edit;
SPContext ctx =
SPContext.GetContext(HttpContext.Current,
DataItem.ID, DataItem.ListItems.List.ID,
DataItem.ListItems.List.ParentWeb);
((UserField)ValElem).ItemContext = ctx;
((UserField)ValElem).RenderContext = ctx;
Technorati Tags: , ,

вторник, августа 05, 2008

Бесплатный антивирус в Windows

Довольно давно приладился использовать бесплатный антивирус ClamWin на Windows Server 2003. Его же использую и на Vista x64, и на Windows Server 2008.
Недавно обнаружил, что во "временных" папках могут встречаться "подозрительные", по мнению антивируса, файлы. Что ж, не жалко, настроил через планировщика самого антивируса сканирование этих папок раз в день (во время обеда, чтоб не мешалось). Живём дальше... smile_wink