Monday, December 28, 2009

Как убрать "Действия" или "Создать " в списке или библиотеке документов

В Интернете много решений этой проблемы, в большинстве своём они весьма объёмны и задействуют jquery, просто громоздкие джаваскрипты или изменение системных шаблонов Sharepoint. Я решила пойти по более простому пути.
Сначала открываем исходный код страницы с нужным представлением - в моём случае это был "Календарь" - и находим там кнопку "Действия". Код выглядит примерно так:
<span title="Открыть меню">
<div id="zz17_ListActionsMenu_t" class="ms-menubuttoninactivehover" onmouseover="MMU_PopMenuIfShowing(this);MMU_EcbTableMouseOverOut(this, true)" hoveractive="ms-menubuttonactivehover" hoverinactive="ms-menubuttoninactivehover" onclick=" MMU_Open(byid('zz11_ActionsMenu1'), MMU_GetMenuFromClientId('zz17_ListActionsMenu'),event,false, null, 0);" foa="MMU_GetMenuFromClientId('zz17_ListActionsMenu')" oncontextmenu="this.click(); return false;" nowrap="nowrap">
<a id="zz17_ListActionsMenu" accesskey="C" href="#" style="cursor: pointer; white-space: nowrap;" onfocus="MMU_EcbLinkOnFocusBlur(byid('zz11_ActionsMenu1'), this, true);" onkeydown="MMU_EcbLinkOnKeyDown(byid('zz11_ActionsMenu1'), MMU_GetMenuFromClientId('zz17_ListActionsMenu'), event);" onclick="javascript:return false;" oncontextmenu="this.click(); return false;" menutokenvalues="MENUCLIENTID=zz17_ListActionsMenu,TEMPLATECLIENTID=zz11_ActionsMenu1" serverclientid="zz17_ListActionsMenu">
Действия
<img src="/_layouts/images/blank.gif" alt="Для открытия меню воспользуйтесь сочетанием клавиш SHIFT+ВВОД (в новом окне)." border="0">
a>
<img src="/_layouts/images/menudark.gif" alt="" align="absbottom">
div>
span>



Мы видим, что ID div'а, в который заключена нужная нам кнопка - zz17_ListActionsMenu_t.
Открываем страницу с этим представлением в Sharepoint Designer и в одном из блоков добавляем следующее:
<style type="text/css">
#zz17_ListActionsMenu_t {
  display:none;       
}
</style>


Сохраняем страницу - и вуаля! Кнопки "Действия" больше нет.
Для остальных кнопок на панели инструментов действия аналогичные.

Tuesday, December 08, 2009

создание рабочего процесса в visual studio 2008

Создание рабочих процессов для MOSS 2007 - занятие нетривиальное.
Начнём с того, что, во-первых, для разработки в visual studio 2008 она должна быть установлена на машине с MOSS 2007 (и, соответственно, серверной Windows).
Во-вторых, несмотря на то, что для MOSS рекомендуется 64хбитное окружение, разработка с использованием разрекламированных встроенных шаблонов VS возможна только в 32-битной системе.
Соответственно, заставив работать рабочий процесс на 32хбитной машине для тестов, надо перенести его на 64хбитную ферму, где он будет крутиться в боевом режиме.
Для этого сначала создаём на сервере боевой фермы папку C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\названиеРабочегоПроцесса, куда копируем файлы feature.xml и workflow.xml, любезно созданные Visual Studio 2008 (в папке проекта они находятся в bin\Debug\).
Потом DLL рабочего процесса из той же папки bin\Debug устанавливаем в GAC: есть несколько способов это сделать, я предпочитаю самый простой - просто перетащить в Проводнике файл в C:\WINDOWS\assembly.
ВНИМАНИЕ! Если в ферме несколько серверов, файлы xml и DLL нужно скопировать на ВСЕ СЕРВЕРА! Иначе будут проблемы со своевременным отрабатыванием процесса.
После этого нужно добавить feature (возможность?). Для этого на одном из серверов запускаем команду:

stsadm -o installfeature -name названиеРабочегоПроцесса

После этого запускаем команду активации:

stsadm -o activatefeature -name названиеРабочегоПроцесса -url http://sharepointsite

Параметр name при этом - название папки в FEATURES, куда были скопированы xml с описанием рабочего процесса, а параметр url должен указывать на корневой сайт Sharepoint.
После этого заходим в библиотеку документов -> Параметры -> Библиотека документов: Параметры -> Параметры рабочих процессов -> Добавить рабочий процесс - и вуаля, в списке появился наш процесс. Ура, товарищи!
Надеюсь, кому-нибудь это поможет :)

Wednesday, December 02, 2009

Ошибка при присоединении базы данных к веб-приложению

Случилась недавно такая проблема: нужно было присоединить к существующему веб-приложению базу данных контента, восстановленную из бэкапа за предыдущий день.
База данных всего занимала 65 гигабайт: после 2х с небольшим часов попытки отрабатывания команды stsadm -o addcontentdb -url http://sharepoint -databasename WSS_Content_Sharepoint80 мне выдавалось сообщение: "Обновление завершено с ошибками".
В файле C:\Program files\Common Files\Microsoft Shared\web server extensions\12\Logs\Upgrade.log писалось следующее:
--------
[SPContentDatabaseSequence] [DEBUG] [30.11.2009 21:55:53]: Executing database object restore script.
[SPUtility] [DEBUG] [30.11.2009 21:55:53]: File C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Template\sql\storeup.sql, Time out = 7229 sec
[SPManager] [ERROR] [30.11.2009 23:56:33]: Upgrade [SPContentDatabase Name=WSS_Content_Sharepoint80 Parent=SPDatabaseServiceInstance] failed.
[SPManager] [ERROR] [30.11.2009 23:56:33]: Истекло время ожидания. Время ожидания истекло до завершения операции или сервер не отвечает.
[SPManager] [ERROR] [30.11.2009 23:56:33]: в System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
--------
Как показало наблюдение за попыткой выполнить команду addcontentdb, к моменту наступления таймаута обычно выполнялся запрос
  1. IF NOT EXISTS (SELECT id FROM sysindexes WHERE id = object_id(N'[dbo].[AuditData]') AND name = N'AuditData_OnSiteOccurredEvent')
  2. BEGIN
  3.     CREATE CLUSTERED INDEX AuditData_OnSiteOccurredEvent ON AuditData (SiteId, Occurred, Event)
  4. END
* This source code was highlighted with Source Code Highlighter.

Этот запрос был взят из упомянутого в логе Upgrade.log файла storeup.sql.
Также выяснилось, что таблица AuditData занимает 37 гигабайт (из 65 всей базы), а содержит отчёты о деятельности пользователей (которые всё равно никто не просматривает).
После чего была запущена команда Truncate Table AuditData, и была запущена снова команда addcontentdb, на этот раз завершившаяся успешно.
При попытке вернуть данные в AuditData на место снова было получено изначальное сообщение об ошибке. Поскольку эти данные пока что никому не были нужны, оставляю их в бэкапе и предоставляю накапливаться новым.
Надеюсь, кому-то это окажется полезным, и спасёт от недельного (как было в моём случае) бесплодного мозгоимения.

Thursday, November 12, 2009

Sharepoint Backup

Вот такой скрипт на PowerShell я накреативил для бэкапа своей фермы Sharepointа и файлов IIS, слегка переработав вот этот. Он создаёт бэкапы встроенной утилитой stsadm, удаляет старые (количество бэкапов для сохранения задаётся в переменной $days), копирует содержимое папок узлов Sharepoint в IIS и сохраняет конфиг IISа, после чего пишет в Event Log.

#path where the backups will be
$path = "\\backup-server\Sharepoint\"
#how many days of backup should there be
$days = 1
#path to stsadm utility
$stsadm = "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\STSADM.EXE"
#run stsadm.exe with necessary parameters
#&$stsadm -o backup -directory $path -backupmethod full -quiet -overwrite
# copy contents of Inetpub
Copy-Item "C:\Inetpub\wwwroot\wss\VirtualDirectories" $path -Recurse -Force
#copy IIS configuration files
Copy-Item "C:\WINDOWS\system32\inetsrv\MBSchema.xml" $path -Force
Copy-Item "C:\WINDOWS\system32\inetsrv\MetaBase.xml" $path -Force
# CLEANING OLD BACKUPS
# get contents of the spbrtoc.xml
[xml]$spbrtoc = gc ($path + "spbrtoc.xml") -Encoding UTF8
# find info about the old backups
$oldBackups = $spbrtoc.SPBackupRestoreHistory.SPHistoryObject | ? { $_.SPStartTime -lt ((get-date).adddays(-$days)) }
$oldBackups.Count
if ($oldBackups -eq $Null) {
#Application Log event details
$eventdetails = "Backup and cleanup info from sharepoint_backup.ps1: no old backups for removal"
} else {
#Application Log event details
$eventdetails = "Backup and cleanup info from sharepoint_backup.ps1: removed " + $oldBackups.Count + " old backups";
# remove them from the xml
$oldBackups | % { $spbrtoc.SPBackupRestoreHistory.RemoveChild($_) }
# remove their folders from the backup location
$oldBackups | % { Remove-Item $_.SPBackupDirectory -Recurse }
# Save the modified xml
$spbrtoc.Save($path + "spbrtoc.xml")
}

# Write to Application Log
$event=new-object System.Diagnostics.EventLog("Application")
$event.Source="Sharepoint Backups"
$eventtype=[System.Diagnostics.EventLogEntryType]::Information
$event.WriteEntry($eventdetails,$eventtype,1337)

Tuesday, October 13, 2009

it's all too much

Интересно, сколько людей поймёт всё в этой бугаге.
Кстати, остальные там комиксы тоже хороши. По крайней мере, для посвящённых :)

Monday, October 12, 2009

обновление информации в профиле

Столкнулась сегодня с интересной проблемой: при обновлении e-mail'а в профиле пользователя через администраторский интерфейс в SSP, он оставался старым в профиле на основной странице портала. Причём если этого пользователя удалить, а потом создать заново с новым e-mail'ом - всё равно почта на странице профиля в портале была самой первой.
На второй день гугления всё прояснил пост на форуме MSDN: как оказалось, в SSP на странице со всеми свойствами профиля ( /ssp/admin/_layouts/MgrProperty.aspx ) у электронной почты не стояла галка "реплицируемый". Стоило её поставить и запустить добавочный импорт - всё быстренько обновилось :)
Теперь следующий вопрос для расследования - где ещё у Sharepoint'a хранятся свойства профиля, что с чем в этом случае не синхронизовалось? Судя по гуглю, база MySite и база основного сайта, но как-то странно, что профили у них разные о_О Впрочем, это уже не столь важно на данный момент.

Monday, September 14, 2009

оповещение из рабочего процесса

Если вы сделали рабочий процесс (workflow), который в процессе работы отсылает оповещение о чём-либо (например, о создании нового элемента в списке), а это оповещение мало того, что не приходит, так ещё и сам рабочий процесс не запускается при создании - не спешите лопатить Гугель, рвать на себе волосы и запасаться ящиком пива для усердного дебага. Для начала надо проверить: не создаёте ли вы тестовый элемент из-под системной учётной записи.
Потому что если это так - ничего вам и не придёт: как написано в этой статье, рабочие процессы не запускаются, если операции с элементом выполняет системный пользователь. По крайней мере, если у вас стоит SP1 для Sharepoint'a.
Я на это напоролся - надеюсь, вы этого избежите :)

Friday, September 11, 2009

Особое сообщение об ошибке

Сейчас я пишу настраиваемый список (custom list) с отдельным типом содержимого (content type), а также с парочкой обработчиков событий (event handlers). В процессе тестов на машине для разработки я наткнулся на интересный баг: несмотря на то, что в моём коде было прописано собственное сообщение об ошибке при невыполнении некоторых условий, почему-то вместо него мне показывали совсем другое: элементу управления источника данных не удалось выполнить команду обновления или, на языке оригинала, The data source control failed to execute the insert command.
Долгое гугление показало, что ошибка эта случается довольно регулярно, и для её исправления надо поставить Windows Sharepoint Services 3.0 Infrastructure Update. А ещё желательно SP1 для MOSS 2007 до и MOSS 2007 Infrastructure Update после него.
Что характерно, SP1 мне поломал IIS: после его установки куда-то безвозвратно пропал файл %systemroot%\inetsrv\MBSchema.xml, и пришлось его и MetaBase.xml восстанавливать из %systemroot%\inetsrv\History. Но это - совсем другая история.. Хорошо ещё это был тестовый сервер :)
Будьте осторожны с продукцией M$, друзья :)

PS до чего же сложно писать на такие темы по-русски: половина терминов существует исключительно в английском языке%) К примеру, перевод слова custom как настраиваемый мне совершенно не нравится - от него представляется не куча кода, а обычная страница выбора настроек с галочками. Но что ж поделать :)

Thursday, August 27, 2009

Запуск скрипта на Powershell через GET запрос

Как-то понадобилась нам хитрая штука: передавать через строку браузера некоторое количество параметров в скрипт на Powershell, потом получать от него Exit Code и его выводить.
Я долго читал про разные способы запуска PS из C#, изучил пространства имён
System.Collections.ObjectModel, System.Management.Automation и System.Management.Automation.Runspaces так, что они начали сниться мне по ночам, Firefox ломился от табов вроде такого и такого..
А потом меня, как водится, осенило. От самого скрипта мне не нужно было никакого вывода: только код завершения. Поэтому вполне можно было не заморачиваться с обработкой PS через C#, а сделать намного проще.
Сначала получаем параметры из GET-запроса в строке:
  1. string strParameters = "";
  2. foreach (string strParameter in Request.QueryString)
  3. {
  4. strParameters += " " + strParameter + ":" + Request.QueryString[strParameter];
  5. }
* This source code was highlighted with Source Code Highlighter.

А потом запускаем процесс со скриптом и параметрами. Что самое забавное, этот скрипт довольно универсален: имя скрипта тоже можно передавать в качестве параметра.
  1. Process Powershell = null;
  2. if (File.Exists(strScriptDirectory + strScriptName))
  3. {
  4. Powershell = Process.Start("powershell", @"-noexit -command " + strScriptDirectory + strScriptName + strParameters);
  5. while (!Powershell.WaitForExit(1000)) ;
  6. strExitCode = Powershell.ExitCode.ToString();
  7. }
* This source code was highlighted with Source Code Highlighter.

Как обычно, всё гениальное просто. Надеюсь, кому-нибудь это поможет:)

Wednesday, August 19, 2009

Панель редактирования страницы не отображается у одного из пользователей

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

Сегодня у меня случилось просветление. Я открыл "Действия узла" -> Параметры узла -> Изменение параметров узла, там выбрал "Возможности узла". Так и есть! "Публикация Office Sharepoint Server" была отключена.

Как только я нажал на "Активировать" - всё стало правильно, и в меню "Действия узла" появились необходимые пункты: в том числе и "Показать меню изменения страницы".
Надеюсь, это кому-нибудь окажется полезным :)