пятница, июля 28, 2006

Ghost from SharePoint

Потребовалось сделать обход всех существующих структур Шарепойнта и достать все библиотеки документов и рисунков. Выяснилось, что в базе существует много объектов, которых как бы и нет (на страницах не отображаются), но в объектную модель попадают. На них вылетают всякие исключения, которых вовсе не ожидаешь, но которые в итоге следует учитывать. После всех этих «учётов» ожидаемый метод из 10 строк вылился вот во что (здесь log – мой собственный логгер, к делу не относится):
 
/// <summary>
///
Выдаёт все библиотеки документов

/// </summary>

/// <returns>очередную библиотеку </returns>

/// <remarks>вызывать в цикле вида

/// foreach (SPDocumentLibrary lib in DocLibs()){ ... }

/// </remarks>

IEnumerable< SPDocumentLibrary>DocLibs() {

    SPGlobalAdmin ga = new SPGlobalAdmin();

    string[] vsNames = ga.VirtualServerNames;

    for(int vs=0;vs<vsNames.Length;vs++){

        SPVirtualServer srv = null;

        try {

            srv = ga.VirtualServers[vs];

        } catch (Exception err) {

            log.WriteException(err, false, vsNames[vs], 68);

            continue;//next VirtualServer

        }

        int nSites = -1;

        try {

            nSites = srv.Sites.Count;

        } catch { }

        if (nSites > 0) {

            string[] siteNames = new string[srv.Sites.Count];

            for (int s = 0; s < siteNames.Length; s++)//fill names

                try {

                    siteNames[s] = srv.Sites[s].Url;

                } catch {

                    siteNames[s] = null;

                }

            foreach (string siteName in siteNames) {

                if (string.IsNullOrEmpty(siteName)) continue; //next Site

                SPSite site = null;

                try {

                    site = new SPSite(siteName);

                } catch (Exception err) {

                    log.WriteException(err, false, siteName, 69);

                    continue; //next Site

                }

                site.CatchAccessDeniedException = false;

                string[] webNames;

                try {

                    webNames = site.AllWebs.Names;

                } catch (Exception err) {

                    log.WriteException(err, false, siteName, 691);

                    continue; //next Site

                }

                foreach (string webUrl in webNames) {

                    SPWeb web = null;

                    try {

                        web = site.AllWebs[webUrl];

                    } catch (Exception err) {

                        log.WriteException(err, false, webUrl, 70);

                        continue;//next web

                    }

                    int listsCount=-1;

                    try {

                        listsCount=web.Lists.Count;

                    } catch { }

                    if (listsCount > 0) {

                        string[] listNames = new string[listsCount];

                        for (int l = 0; l < listsCount; l++) {

                            try {

                                listNames[l] = web.Lists[l].Title;

                            } catch (Exception err) {

                                log.WriteException(err, false,

                                         string .Format("List number {0}", l + 1), 71);

                                 listNames[l] = string.Empty;

                             }

                         }

                         foreach (string listName in listNames) {

                             if (!string.IsNullOrEmpty(listName)) {

                                 SPList list = null;

                                 try {

                                     list = web.Lists[listName];

                                 } catch (Exception err) {

                                     log.WriteException(err, false, listName, 72);

                                     continue; //next List

                                 }

                                 if (list != null && list is SPDocumentLibrary)

                                     yield return list as SPDocumentLibrary;

                             }

                         }

                     }

                     web.Dispose();                }

                site.Dispose();            }

        }

    }

    ga.Dispose();

}

понедельник, июля 24, 2006

Опять прикол от SharePoint

Нужно было воспользоваться свойством списка list.LastItemModifiedDate - gets the date and time that an item, field, or property of the list was last modified.

При этом время выдаётся по Гринвичу независимо от региональных установок на объектах SPWeb и SPSite. Выкрутился использованием конструкции
  list.ParentWeb.RegionalSettings. TimeZone.UTCToLocalTime(list.LastItemModifiedDate )

В это же самое время для отдельных items списка данные, например, list.Items [0]["Modified"], выдаются в соответствии с региональными установками.

Вот же, блин. Горелый.

четверг, июля 13, 2006

Встраиваемые СУБД

В проекте потребовалось сохранять промежуточные данные, чтоб потом их считывать. Можно, конечно, сериализовать и сохранять в файл (двоичный или xml), но подумалось, что попользоваться базой данных проще и привычней. База там, естественно, есть, однако это MS SQL Server, занятый своей собственной неслабой работой, поэтому сразу решил поискать чего-то встраиваемого в саму программу, небольшого размера и, желательно, бесплатного.

Вот результаты изысканий:

Vieka eSQL – бесплатная для любого применения, платить нужно только при использовании в продажных продуктах для мобильных девайсов. Для использования требуются библиотеки размером ок. 450 кб. Наследник SQLite, имеет минимальный набор типов, с небольшими базами работает быстро (при размерах в сотни мегабайт народ жалуется на тормоза). Имеет интерфейс с .NET, работает с SQL-92. База однофайловая. Требуются операции сжатия базы. Имеется пример, который получается изменять – бум смотреть в качестве кандидата.

db4o
– распространяется по GPL. Для использования требуются библиотеки размером ок. 860 кб. Имеется интерфейс с .NET 2.0 и .NETCF 2.0. Объектная база. Народ жалуется на задержки при открытии файла базы. База однофайловая. Мало какой-либо хорошей информации, хотя имеющиеся примеры работают.

SQL Server Everywhere Edition – пока что существует в виде CTP, но к концу года обещают выпустить релиз, да ещё и бесплатный. Для использования требуются библиотеки размером ок. 1.5 Мб. Имеется интерфейс с .NET 2.0 и .NETCF 2.0. Программная модель – как у SQL Server 2005. База однофайловая. Штука привлекательная, надо её поизучать на будущее.

VistaDB – продаётся за деньги, но лицензия позволяет распространять использующий базу продукт бесплатно. Для использования требуются библиотеки размером ок. 650 кб. Имеется интерфейс с .NET 2.0, работает с SQL-92. Также имеется интерфейс DDA – прямой доступ к данным, быстрая работа на низком уровне с таблицами, записями и т.д. Набор типов почти как у SQL Server. База однофайловая. Примеры работают, поддаются изменению.

Пост из Word 2007

Обнаружилась встроенная фича – постить в блоги.

Щас и проверим.


Это наляпано в Word’е 2007 beta2

Всё, вроде, ничего, даже постит в блоги на Sharepoint 2007. Повторный пост воспринимается как новый, в Шарепойнте заменяет старый.

среда, июля 05, 2006

Sharepoint 2007

После установки Office Sharepoint Server:
 
в Рефлекторе вот такое -
[Obsolete( "This class is obsolete.")]
public class Area{ ... }
И все портальные структуры тоже. Слава богу, что от чепухи отказались.

Добавились разные хитрые шаблоны узлов и сервисы, но на моём тестовом "сервере" они не фурычат (жидковата машинка, конечно).
 

вторник, июля 04, 2006

Sharepoint 2007 (WSS v.3)

Из того, что пока увиделось (повозился с WSS 3):
  • блог и WiKi - вполне рабочие сайты.
  • Discussion - уже совсем на форум похожа, хоть с мелкими глюками.
  • Списки - в ссылочных полях можно делать множественный выбор, список с другого сайта подключить не получилось (хотя и были разговоры о подобных пряниках).

 

четверг, июня 29, 2006

Срок службы Windows Server 2003.

Экспериментально установился, на собственной шкуре (вернее, на компьютере).
 
Установлена система была в 2002 г. (upgrade с Server 2000 через RC). Машина использовалась в качестве стенда:
  • Sharepoint 2001
  • Sharepoint 2003, sp1, sp2
  • MS SQL 2000, sp1, sp3
  • MS SQL 2005, sp1
  • Oracle 7,8,9
  • Pervasive
  • Галактика разных версий
  • антивирусы/firewall'ы разные
  • всякое другое по мелочам (чистилки реестра, дефрагментаторы, архиваторы и проч. ФАРы)
Ставилось, сносилось, работало в разнообразных комбинациях. Переустанавливалась в режиме обновления с сохранением всех настроек один раз в начале 2006 г.
 
Вчера пришлось переустановить с полной очисткой диска - новый софт уже не ставился - .NET 3, Sharepoin 2007.
Бум смотреть, на сколько теперь хватит.

среда, июня 28, 2006

Приколы SQL 2005.

При установке получил сообщение:
 
Could not get performance counter registry info for msftesqlFD for instance SQL2K5 due to the following error : The operation completed successfully . 
 
Хи-хи. 

понедельник, июня 26, 2006

Приколы продолжаются

Друзья из MS статейку на днях вывесили. Теперь придётся код перебирать, чтоб ихние рекомендации реализовать.

In scenarios in which you use SharePoint objects extensively―for example, in SharePoint sites that use custom Web Parts―you can cause the following unusual behaviors by not disposing of those objects that can be disposed of:
  • Frequent recycles of the Microsoft Windows SharePoint Services application pool, especially during peak usage
  • Application crashes that appear as heap corruption in the debugger
  • High memory use for Microsoft Internet Information Services (IIS) worker processes
  • Poor system and application performance

Several of the Windows SharePoint Services objects, primarily the SPSite class and SPWeb class objects, are created as managed objects. However, these objects use unmanaged code and memory to perform the majority of their work. The managed part of the object is small; the unmanaged part of the object is much larger. Because the smaller managed part of the object does not put memory pressure on the garbage collector, the garbage collector does not release the object from memory in a timely manner. The object's use of a large amount of unmanaged memory can cause some of the unusual behaviors described earlier. Calling applications that work with IDisposable objects in Windows SharePoint Services must dispose of the objects when the applications finish using them. You should not rely on the garbage collector to release them from memory automatically.

Вроде, пару лет назад всего этого никто не знал... И, самое смешное, и в "новой" версии всё так же и осталось.

воскресенье, июня 18, 2006

Indigo(WCF) & Win Mobile 5.0

Не нашлось способа подключиться к WCF-сервису в программе для Windows Mobile 5.0.

Облом происходит на строчке
EndpointAddress address = new EndpointAddress (svcUri, null);
Рассказывает, что cannot convert from 'System.Uri [g:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0WindowsCE\System.dll]' to 'System.Uri'
Получается, что эти самые URI в "большом" FW и в CF - совсем уж непохожие.
В общем, опять недоделка...
Бум пока через веб-сервис, по старинке.

четверг, июня 15, 2006

PROMT.

На форуме навели на мысль - сделать в портале "встроенный переводчик". Получилось не хуже Research-панели от Офиса.

пятница, июня 09, 2006

Sharepoint - очередной прикол.

При чтении данных списка посредством вызова метода GetList веб-сервиса http://Server_Name/[sites/][Site_Name/]_vti_bin/Lists.asmx получаем исключение с сообщением "There is an error in XML document (94, 5)." И всё.
Выяснилось, что в текстовом поле списка имеется символ \0x31. Откуда взялся, неведомо, да и не повод это для такого поведения. Тем более, при чтении через объектную модель ничего плохого не происходит. Рисуется квадратик на месте символа.

P.S. Что означают числа 94,5 в сообщении, выяснить так и не удалось. India forever.

среда, мая 24, 2006

WSS Login

Многие сомневаются в существовании означенной веб-части. Вот же она - в виде кнопки "Вход":


вторник, апреля 18, 2006

Sharepoint WebParts in VS 2005

Последнее усилие получить что-то пристойное в смысле использования Visual Studio 2005 для разработки WebPart'ов для Sharepoint'а.
Вот здесь - шаблон проекта. С его помощью создаётся вполне работоспособное хозяйство для разработки и компиляции веб-частей.
Где-то также нашлись codesnippet'ы, но не очень интересные, по-правде. В общем, для редактирования 2005-я студия получше будет.
Только вот с отладкой - никак, 2005-я нужного режима вовсе не имеет. Сделал проект на 2003-й Студии, включил туда тексты (отладка не запускается без компиляции) - и можно отлаживать. Если не очень часто это делать - пригодно для жизни получилось.

воскресенье, апреля 16, 2006

Очередной прикол Sharepoint

При копировании списков для полей типа SPFieldNumber использовал конструкцию:

newfield.MaximumValue = field.MaximumValue;

newfield. MinimumValue = field.MinimumValue;

Первая строчка проходит, на второй же вылетает исключение с сообщением типа "Значение сильно большое или сильно маленькое для типа Double". Проходит только значение по умолчанию (ок. -1e308, когда значение не устанавливалось), если в исходном списке такое значение было установлено, то кранты. Через Reflection нужное значение присвоить тоже не удаётся. :-(
Хуже того, исполнение первой строчки вызывает то же исключение при попытке отредактировать это поле в интерфейсе _layouts/1049/FldEdit.aspx.

Пришлось в Админе от установки этих свойств отказаться с выдачей предупреждения.

Вот, блин.

понедельник, марта 27, 2006

MSMQ on Windows Mobile 5

Решил попользоваться означенной фигнёй.
Скачал дистрибутив, установил – не работает :-(
Порылся в Гугле, выяснилось, что это у многих так. Но поправимо – надо руками активировать сей девайс:

[DllImport("coredll.dll",CharSet=CharSet.Unicode)]
public static extern IntPtr ActivateDevice(string lpszDevKey, int dwClientInfo);
...
IntPtr id = ActivateDevice(@"Drivers\BuiltIn\MSMQD", 0);
...

После этого хозяйство подаёт признаки жизни.

Дальше сделал попытку создать очереди и сунуть в них сообщения – ну, по примерам в MSDN и проч. литературе.
private void Testmenu_Click(object sender, EventArgs e) {
Qname = @"FormatName:DIRECT=OS: DkmServ\qtek";
Qname = @".\Private$\ttrqueL";
Qname = @".\ttrqueP"; MessageQueue.GetMachineId(".");
if (!MessageQueue.Exists(Qname)) {
msgs = MessageQueue.Create(Qname);
} else {
msgs = new MessageQueue(Qname);
}
msgs.Send("Hello, Прювет");
} catch (Exception err) {
MessageBox.Show(err.Message, err.GetType().Name);
}
}

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

четверг, марта 16, 2006

Очередной прикол Sharepoint

Обнаружил, что в одном месте - в базе данных содержимого Sharepoint (в случае портала - в базе portal1_SITE) в таблице Sites (поле FullUrl ) пишутся абсолютные значения адресов (наподобие http://server/sites/site1).
Пишутся они туда только для узлов верхнего уровня в момент их создания и, похоже, больше нигде не используются. Вместо них можно свободно написать любые матерные слова, сайты работают нормально.
Во всех остальных местах пишутся относительные адреса сайтов и узлов.

Реликт какой-то, похоже...

воскресенье, марта 05, 2006

Секреты, едрёныть :(

Возился с задачами Outlook на десктопе и на мобиле. Всё хорошо и красиво, синхронизируются, можно что-то записать, записанное хранится.Но только на первый взгляд. На второй взгляд – неясно, как синхронизируется: идентификаторы на десктопе и на мобилке друг на друга вовсе не похожи. Где-то ещё таблицы должны храниться...Кроме того, добавляемые пользовательские свойства (даже с одинаковыми именам) не пересылаются. Вот же блин!

суббота, февраля 11, 2006

Очередной прикол Sharepoint'а

Теперь прикол от Sharepoint Portal.

При копировании веб-части в файл столкнулся с тем, что иногда имеет значение порядок присваивания некоторых свойств веб-части.
Например, свойство ZoneID следует назначать после добавления новой веб-части к целевой коллекции.

WebPart dst = new WebPart ();
SPWebPartCollection wpc = file.GetWebPartCollection(Storage
.Shared);
Guid
ID = wpc.Add(dst);
WebPart ds = wpc[ID];
//добавленный контрол
ds.ZoneID = ZoneID;
//присвоить значения другим свойствам
wpc.SaveChanges(ID);

Оказалось, на страницах портала есть зоны (одна из них - TitleBar), которым небезразличен порядок действий.

пятница, февраля 10, 2006

Sharepoint & Anthem.NET

Nice work Anthem.NET I used in the small Web-part, containing TextBox and LinkButton . For the conclusion of communications there is Label control.

The method of use came out sufficiently simple.
Connecting to namespace Anthem:
#if AJAX
using
Anthem;
#else
using System.Web.UI.WebControls;
#endif

Addition of specific properties in method OnInit:
#if AJAX
btn.TextDuringCallBack = "..Wait";
btn.EnabledDuringCallBack = false;
#endif

Everything earned after this, as it was expected:
- the button is blocked to the period of the fulfillment of actions, the inscription is derived on it"..Wait"
- on the return draw again only changed elements (button, label and text field), without the stupid pulling of the entire page.

Underwater stones thus far were located two:
1. During the changes in js-code and the recompilation of project Anthem-2003 is necessary cleaning AppPool the corresponding Web site.
2. Values UpdateAfterCallBack=true; in method OnInit to establish one ought not - immediately occurs copying with the original values. To establish them is possible either in the events handlers or in the beginning of method RenderWebPart.

Sharepoint & Anthem.NET

Отличную разработку Anthem.NET использовал в небольшой веб-части, содержащей TextBox и LinkButton (не считая выполняемых действий). Для вывода сообщений имется Label.

Метод использования получился довольно простой.

В файле вебчасти, использующей web-контролы, подключил пространство имён Anthem:
#if AJAX
using Anthem;
#else
using System.Web.UI.WebControls;
#endif

В методе OnInit для имеющейся на веб-части кнопки btn добавил cпецифические свойства:
#if AJAX
btn.TextDuringCallBack = "..Wait";
btn.EnabledDuringCallBack =
false;
#endif

Собственно, после этого всё заработало, как и ожидалось:
- на время выполнения действий кнопка блокируется, на ней выводится надпись "..Wait"
- по возврату перерисовываются только изменившиеся элементы (кнопка, метка и текстовое поле), без дурацкого дёргания всей страницы.

Подводных камней пока нашлось два.
1. При изменениях в js-коде и перекомпиляции проекта Anthem-2003 необходима очистка AppPool соответствующего веб-сайта.
2. Значения UpdateAfterCallBack=true; в методе OnInit устанавливать не следует - сразу происходит перерисовка исходными значениями. Устанавливать их можно или в обработчиках событий или в начале метода RenderWebPart.

четверг, февраля 09, 2006

«About» ToolPart continued

В развитие примочки перенёс в эту панель запуск функции, которая запускалась из меню веб-части и не давала покоя любопытным юзерам. Сделал там кнопочку, всё хорошо, всё выполняется. Ура!

Но Microsoft не дремлет! И тут нашлась засада...

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

ParentToolPane.OK.Visible =
ParentToolPane.Cancel.Visible =
ParentToolPane.Apply.Visible = false;

Минное поле...

пятница, января 27, 2006

«About» ToolPart

Подсмотрел у кого-то и поразвивал примочку для вывода панельки «About…» в панели настройки веб-части.
Сам класс панели :

public class About: Microsoft.SharePoint.WebPartPages .ToolPart
{
      public About()
      {
            this . Title = "O
веб -части..." ;
      }
      string bCard="© DkmS, 2005..06 ";
      /// <summary>
      /// Parent Webpart
      /// </summary>
      public WebPart ParentWP{
            get{return parent;}
            set {parent= value;}
      }
      protected override void OnInit(EventArgs e) {
            base .OnInit (e);
      }
      public override void ApplyChanges(){}
      public override void SyncChanges(){}
      public override void CancelChanges(){}
      protected override void RenderToolPart(HtmlTextWriter output){
            output .Write("<center>" );
            output.Write( "<div title='"+bCard +"'>");
            output.Write("<br><b>My cool WebPart.</b><br><br>" );
            output.Write("</div>");
            output . Write("</center>");
            output.Write("<br><br><hr>" );
      }
}

Использование:

В вызывающем классе изменяем метод

public override ToolPart[] GetToolParts() {
      ToolPart[] baseTP = base .GetToolParts ();
      ToolPart[] myTP =new ToolPart[3];
      WebPartToolPart std=baseTP[ 0] as WebPartToolPart;
      CustomPropertyToolPart myprops=baseTP[1] as CustomPropertyToolPart;
      myTP[0]=myprops;

      myTP[2]=std;
      About about=new About();
      about.ParentWP= this;
      myTP[1]=about;
      return myTP;
}

среда, января 25, 2006

Обработка обращения к IIS по "неправильному" порту.

Сильно похоже, что до web-сервера запросы вида http://server:port в случае, когда обработка такого порта на самом сервере не предусмотрена, просто не доходят.
Сообщение типа The page you are looking for is currently unavailable (вариант английского IE) формирует сам браузер. Например, русский Firefox в таких случаях сообщает: Попытка соединения не удалась. Firefox не может установить соединение с сервером server:port. У IE такая же реакция наблюдается и при обращении к заведомо несуществующему серверу (http://nonexistserver). FF при этом пытается организовать поиск при помощи Google.
 
Поэтому сделать некий универсальный обработчик таких обращений невозможно. Можно лишь сделать обработку ставших недействительными существовавших ранее обращений путём организации виртуального сервера, обрабатывающего запросы с использованием "неверного порта". При обработке можно как перенаправлять запросы, так и формировать какие-либо сообщения.
 

четверг, января 19, 2006

Очередной прикол от Sharepoint

При реализации "Удаления" записей списка в "корзину" добавил к списку поле _deleted_ типа Boolean, в который ставил признак "удаления".
Но не всё так просто, MS лёгких путей не ищет:
конструкция list.Items.GetDataTable(); иногда возвращает в этом поле DBNull, иногда и правильные значения.
В итоге пришлось сделать поле целого типа и проверять на == 1.
 
Блин.

Application settings in C# 2.0 continued

Обнаружилась засада - не может засады не быть!
 
Для проекта типа "Class Library" можно задать настройки ровно так же, как и для проекта "Application". Разница небольшая - при загрузке сборки чтения конфига не происходит. Даже принудительное перечитывание при помощи settings.Reload(); ничего не прибавляет. Модуль работает с теми значениями настроек, которые были записаны в качестве default'ных.
 
Пришлось написать процедуру считывания значений настроек.

void LoadSettings(ref object settings) {
    PropertyInfo[] props = settings.GetType().GetProperties();
   
string path = this.GetType().Assembly.Location;
   
string cfgpath=path+".config";
   
if (! File.Exists(cfgpath)) return;
   
XmlDocument cfg = new XmlDocument();
   
try {
        cfg.Load(cfgpath);
    }
catch (Exception err) {
        ....
       
return;
    }
   
foreach (PropertyInfo prop in props) {
       
if (!prop.CanWrite) continue;
       
XmlNode setting = cfg.SelectSingleNode("//setting[@name = '" + prop.Name + "']" );
       
object value = "";
        if (setting != null) {
            
try {
                value = setting.SelectSingleNode(
"value").InnerText;
               
prop.SetValue(settings, value, null);
           
} catch { }
        }
    }
}

Использование:

object osettings = new Settings();
LoadSettings(
ref osettings);
settings = (
Settings)osettings;

Примечание. При настройке параметров в VS 2005 область действия (Scope) следует установить User (иначе будет сгенерён класс Settings с readonly свойствами).

вторник, января 17, 2006

«Секретная» страница

Соорудил aspx-страницу с авторизацией.
Для каждого юзера выдаётся список предназначенных для него файлов, которые можно сгрузить.
Регулируется вот таким конфигом:

<?xml version="1.0" encoding="utf-8" ?>
<users>
<user dirs="adir" pwd="ap" name="anton">
<user dirs="*" pwd="dp" name="DkmS">
</users>


Вполне даже симпатично получилось. Заодно кой-чему научился.

воскресенье, января 15, 2006

Settins & Versions

Хорошая вещь Properties.Settings, но не до конца продуманная.
Засада - в хранении пользовательских настроек. Без всяких споров/разговоров сохраняются в файле %USERPROFILE%\Local Settings\Application Data\<Company Name>\<appdomainname>_<eid>_<hash>\<verison>\user.config .
И вот из-за этой <verison> и всё горе - используется значение атрибута assembly:AssemblyVersion , которое у меня обычно выставляется автоматом наподобие "1.0.0.*", что довольно удобно при протоколировании . Но при отладке всё, естественно, корёжится.
Пришлось начать использовать атрибут assembly:AssemblyFileVersionAttribute, который студия (Express, по меньшей мере) автоматом менять не умеет. Для получения версии исполняемого файла пользуюсь процедурой
public static string AnyVersion( Assembly assembly) {
object[] attrs=null;
try{
    attrs=assembly.GetCustomAttributes(
typeof(AssemblyFileVersionAttribute ),false);
}
catch{}
if (attrs != null && attrs.Length > 0) {
   
return ((AssemblyFileVersionAttribute)attrs[0]).Version;
}
return assembly.GetName().Version.ToString(4);
}
 
Использование - AnyVersion(Assembly.GetExecutingAssembly()) или ещё как...

четверг, января 12, 2006

Application settings in C# 2.0

Использование новых возможностей по конфигурированию приложений в VS 2005 применительно к VB.NET описано вот тут.

В C# настройка средствами VS (в т.ч. Express Edition) выполняется точно так же. Отличается, ввиду отсутствия в C# конструкции My.Settings, способ использования этих средств.

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

using MyProgram.Properties;

В соответствующем классе объявить член класса:

private Settings settings = new Settings();

Поля этого класса уже можно использовать по назначению:

this.Size = settings.MainFormSize;

Замечание.

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


среда, декабря 28, 2005

Из Writely

Из C# Express через Word: с заменой абзаца на разрыв строки

/// <summary>
///
Description for XmlView.
/// </summary>
[DefaultProperty("Text"),
ToolboxData("<{0}:XmlView runat=server></{0}:XmlView>"),
XmlRoot(Namespace="XMLviewer")]
public class XmlView : Microsoft.SharePoint.WebPartPages.WebPart {
private const string defaultText = "XmlView";
private string text = defaultText;
private string xml = "";
private string xmllink = "";
private string xsl = "";
private string xsllink = "";
private Evidence evidence=null;
}


XmlWebPart & XmlView continued

Заказчику потребовалось использовать в xslt-преобразователе конструкцию <xsl:apply-templates select="document(file)..."/>
В стандартном XmlWebPart - работает. В моём XmlView - ни в какую.
При раскопках выяснилось, что загружать xsl нужно не конструкцией, которая сама напрашивается

XmlDocument xsl = new XmlDocument();
xsl.
LoadXml(xslScript); //в строке - текст xsl
XslTransform xslt =new XslTransform();
xslt.Load (new XmlNodeReader(xsl));
а немного поширше:

XmlDocument xsl = new XmlDocument();
xsl.
LoadXml(xslScript); //в строке - текст xsl
XslTransform xslt= new XslTransform();
XmlUrlResolver resolver=new XmlUrlResolver();
xslt. Load(new XmlNodeReader(xsl), resolver, XmlSecureResolver .CreateEvidenceForUrl(XslLink));
В .NET 2.0 опять по-другому:

XmlDocument xsl = new XmlDocument();
xsl.Load(
http://...test.xsl
);
XmlUrlResolver resolver=new XmlUrlResolver
();
resolver.Credentials =
CredentialCache
.DefaultNetworkCredentials;
XslCompiledTransform xslt= new XslCompiledTransform();
XsltSettings settings = new XsltSettings
();
settings.EnableDocumentFunction =
true
;
settings.EnableScript =
true
;
xslt.Load(
new XmlNodeReader
(xsl),settings,resolver);

вторник, декабря 13, 2005

Очередной прикол от Sharepoint

Фрагменты
SPList list = web.Lists[ListName];
SPListItem WholeItem = list.Items[0];
WholeItem["Viewers"] = text;
WholeItem.Update();

и

SPList list = web.Lists[ListName];
list.Items[0]["Viewers"] = text;
list.Items[0].Update();


имеют совершенно разный эффект - второй ничего никуда не пишет!

вторник, ноября 29, 2005

WSS & SPS Administrator

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

Более подробно - здесь

пятница, ноября 18, 2005

Microsoft.SharePoint.WebPartPages.XmlWebPart

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

А всего-то и надо было - прочитать из файла xml, преобразовать его через xsl и выдать юзеру. В итоге пришлось изобретать свой аналог, который даже и работает.


четверг, ноября 17, 2005

Sharepoint Portal & .NET 2.0 continued

История не заканчивается.

Установил релиз FW .NET 2.0 (описанное ранее было с beta2) - приключения с атрибутом enableEventValidation закончились.
Обнаружилась бяка хуже - перестала работать как следует функция создания узла в портале. Сам узел создаётся, но до формирования по шаблону дело не доходит - заедает на второй странице " Добавление ссылки на узел".
В итоге в области "Узлы" ссылки на новый узел нет, при первом обращении к узлу по адресу сначала выползает форма выбора шаблонов узла.
Попробовал варианты переключения версии .net на установленном узле портала и установки на сервер с включённым вторым дотнетом - один фиг. Мелочь, но противно.

Правда, у некоторых гладко проходит - Matthew Cosier's Blog: WSS and SPS on .NET 2.0

Но у некоторых - тоже не проходит: Steven Van de Craen's Blog

суббота, ноября 05, 2005

Sharepoint notes 4.

Очередной капкан.
 
При добавлении SPFieldLookup-полей к списку list в примерах рекомендуют нечто вроде:
 
list.Fields.AddLookup(fieldName, lookupListID, fieldRequired);
SPFieldLookup newfield = list.Fields[fieldName] as SPFieldLookup
;
newfield.LookupField = lookupFieldName;
 
Всё это проходит на примерах, где поле называется Title.
 
На самом деле, приходится использовать такой код:

AddLookup(list, fieldName, lookupListID, fieldRequired, lookupFieldName);
SPFieldLookup newfield = list.Fields[fieldName] as SPFieldLookup;
 
...
 
string AddLookup(SPList list, string FieldName, Guid LookupListID, bool FieldRequired, string LookupFieldName) {
XmlDocument fxml = new XmlDocument
();
XmlElement xf = fxml.CreateElement("Field"
);
xf.SetAttribute(
"DisplayName"
, FieldName);
xf.SetAttribute(
"Type", "Lookup"
);
xf.SetAttribute(
"Required"
, FieldRequired.ToString ());
xf.SetAttribute(
"List", LookupListID.ToString("B"
));
xf.SetAttribute(
"ColName", "int1"
);
xf.SetAttribute(
"ShowField"
, LookupFieldName);

return  list.Fields.AddFieldAsXml(xf.OuterXml);

}

Sharepoint notes 3.

Опять обманули...

The Delete method of the SPFieldCollection class deletes the field with the specified display name from the collection.

public void Delete(
   string strName
);

Parameters
strName   A string that specifies the display name of the field
 
На самом деле
strName   must be InnerName.

Sharepoint notes 3.

Опять обманули...

The Delete method of the SPFieldCollection class deletes the field with the specified display name from the collection.

public void Delete(
string strName
);

Parameters
strName A string that specifies the display name of the field
На самом деле
strName must be InnerName.

пятница, ноября 04, 2005

Sharepoint notes 2.

Опять обманули...

The Add method of the SPFieldCollection class creates a field in the collection.

public string Add(
   string strDisplayName,
   Microsoft.SharePoint.SPFieldType type,
   bool bRequired
);

Return Value
A string that contains the display name of the new field.
 
На самом деле
возвращает InnerName для нового поля.

вторник, ноября 01, 2005

Sharepoint notes 1.

При добавлении пользователя в роль пытался сделать так:

role.AddUser(user);

В SDK никаких оговорок по поводу этой конструкции не видно. Исполняется молча, но ничего не добавляет :-( Работает только такая конструкция:

role.AddUser( user.LoginName, user.Email, user.Name, user.Notes + "(added by Wss Admin)");

Мелочь, но время потрачено приличное.

.NET 2.0 release

Начал какие-то исследования по использованию релиза.

Установил на втором компьютере релиз и SDK.
Попробовал собрать на нём при помощи MsBuild проект от 2005-й Студии beta 2. Собирается, и даже работает.

Скомпилил своего Wss Admin'а На 2005-й Студии. Работает как под второй бетой, так и под релизом на "сервере".
Осталось уговорить заказчика перейти на вторую версию (пусть и без Sharepoint'а пока).

понедельник, октября 31, 2005

Пристали с хернёй!!!

Спам-блог, говорят!

Уйти, что ли, отсюда на хрен, да ещё и рекламу организовать...

Завтра не прекратится этот идиотизм - так и сделаю.

Херня продолжается...

Одумались, едрёныть - "Your blog has been reviewed, verified, and whitelisted so that it will nolonger appear as potential spam."

Тем временем надыбал ещё одну системку - Multiply site - вполне пристойное место для жизни. И даже отсюда импорт постов есть ;-)

воскресенье, октября 30, 2005

Sharepoint Portal & .NET 2.0 continued

После установки релиза FW вылезла ошибка при обращении к классу Microsoft.SharePoint.Security.SharePointPermission в сборке Microsoft.SharePoint.Security, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c.
Это приключилось в вебчасти на фрагменте

web.AllowUnsafeUpdates = true;

Добавление в web.config элемента <safecontrol assembly="Microsoft.SharePoint.Security, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.Security" typename="Microsoft.SharePoint.Security.SharePointPermission" safe="True" /> эффекта не возымело :-(

Пришлось поставить trust level="Full"

VistaDB 2.1 database for .NET has been released

This 2.1 update includes over 60 improvements, including new support for .NET 2.0 and Visual Studio .NET 2005. VistaDB is a small-footprint, embedded SQL database alternative to Jet/Access, MSDE and SQL Server Express 2005 that enables developers to build .NET 1.1 and .NET 2.0 applications. Features SQL-92 support, small 500KB embedded footprint, free 2-User VistaDB Server for remote TCP/IP data access, royalty free distribution for both embedded and server, Copy 'n Go! deployment, managed ADO.NET Provider, data management and data migration tools. Free trial is available for download.

Repost this to your blog and receive a FREE copy of VistaDB 2.1!

суббота, октября 29, 2005

Мои изделия для Шарепойта (My Sharepoint's tools)

На сегодня имеем несколько результатов:
  • Картотека ВШЭ с лихими свойствами. Установлено и работает (с разными приключениями) больше 1000 экземпляров.
  • Список страниц, где можно что-то редактировать. Подвесил разок систему заказчика, пока обшаривал рекурсивно все сайты.
  • Расширенный редактор на базе FCKEditor - аналог системной веб-части. Работает у заказчика, даже какой-то студент что-то совершенствует.
  • Утилита администратора - показывает структуры WSS и Портала (на манер SharepointExplorer) и делает кое-какие действия - копирование, удаление, показ свойств (будет).

Вроде, ничего так, полгода назад ничего про этот "Шарик" не знал.

Sharepoint Portal & .NET 2.0

Ну, блин, забава...
Результат перевода виртуальных серверов фиг знает от чего зависит - от погоды, что ли, или от магнитных бурь каких...

Порядок действий.
  1. Установить второй сервиспак для Sharepoint Services
  2. Установить второй сервиспак для Sharepoint Portal
  3. Перевести веб-сайт (через консоль управления) на работу под версией .NET 2.0
    1. В свойствах сайта на табе ASP.NET включить вторую версию FW.
    2. Организовать специальный AppPool для сайтов под второй версией FW, загнать туда этот сайт.
    3. Identity для этого пула д.б. account, назначенный главным для доступа к содержимому сайтов
    4. Проследить, чтоб в этот пул попали и подсайты _layouts, _vti_bin, _wpresources. Если не попали, загнать их туда вручную через свойства подсайта.
  4. Для модификации web.config выполнить команду stsadm.exe -o upgrade -forceupgrade -url http://YourCoolSite (см. KB894903 ).
    1. Проследить, чтоб прошла модификация, как сказано в KB.
    2. Если модификация не выполнилась, то сделать её вручную, при этом проследить, чтобы в теге pages не было атрибута enableEventValidation (этот же атрибут добавляется при сносе/восстановлении портала через Центр администрирования - похоже на глюк!? ).
  5. Выполнить iisreset.
  6. Лучше бы перезапустить IE.
После этого сайт вполне себе заработал.
Дальше буду пробовать что-то на втором FW сочинить.

понедельник, октября 03, 2005

Google Web Accelerator

Ну и какашка! Сгружает файлы как бы "заранее", а при начале загрузки пользователем качает их снова.
В общем, в 100 Мб трафика мне эта "радость" обошлась. Бля!

четверг, сентября 29, 2005

Sharepoint web-services

Вот бред - просто так в Студии подключить в проект эти сервисы не получается:
The document at the url http://localhost/_vti_bin/sites.asmx was not recognized as a known document type.
 
Помогает написать вместо, например, http://localhost/_vti_bin/Lists.asmx  немного другое -  http://localhost/_vti_bin/Listswsdl.aspx .
 
Ещё вот так срабатывает - http://localhost/sites/test/_vti_bin/Lists.asmx
Прочитал тут - http://blogs.msdn.com/trobbins/articles/220551.aspx

 
Здесь sites/test - существующий сайт.
 
Полный капец

суббота, сентября 03, 2005

DSL-200 on Windows 2003 sp1

Решил тут подключиться к Инету цивилизованным способом - через ADSL-модем.

В конторе провайдера предложили купить модем у них, явно дороже, чем в магазине, но ладно, согласился (в надежде, что бегать покупать не придётся, да и поддержку обещали). Естественно, подсунули самый дешёвый - DSL-200 с USB-интерфейсом. В общем, гадость полнейшая.

Установка.

В начале установки надо обязательно выбрать вариант LAN, указать значения VCI/VPI, как скажет провайдер, и обязательно указать "Bridget LLC Encapsulation":


Дальше можно всё делать по инструкции, в процессе Windows спросит про установку нового устройства - надо согласиться на установку по умолчанию, поставится правильное устройство. В конце длинной процедуры установки драйверов вывалится сообщение, что установка прошла неудачно. Не верить, снять установщик через Task Manager. После перезагрузки запустить DSL-200 Status, нажать там Ctrl-F1, выбрать "Driver Config" и посмотреть, что получилось. Если всё, как ожидалось, можно пробовать работать.


Проверка реестра


Необходимо проверить ключ HKEY_LOCAL_MACHINE\SOFTWARE\GlobeSpanVirata, который должен выглядеть примерно таким образом:

[HKEY_LOCAL_MACHINE\SOFTWARE\GlobeSpanVirata\GVInstDLL]
"OrgTcpipWinSize"=dword:00000000
"DriverType"="LAN"
"Vci"="33"
"Vpi"="0"
"Encapsulation"="2"
"hklmDriverSignPolicy"=hex:01
"hkcuDriverSignPolicy"=hex:01
"Driver"="{4D36E972-E325-11CE-BFC1-08002BE10318}\\0011"
"DriverInstalled"="1"

[HKEY_LOCAL_MACHINE\SOFTWARE\GlobeSpanVirata\GVInstDLL\DriverParameters] "SysTrayIconMode"="1"
"Rfc1483Mode"="0"
"Rfc1577Enable"="0"
"Rfc1483Vci"="33"
"Rfc1483Vpi"="0"
"Standard"="4"
"Win2kSurpriseRemoval"="1"
"Language"="english"
"VendorId"="39"
"CplDebugMode"="1"
"IsLogoTransparent"="0"

Здесь может отсутствовать ключ "Driver", который нужно добавить, а некоторые параметры могут иметь неверное значение - их надо исправить.

В разделе HKEY_LOCAL_MACHINE\SYSTEM найти параметры Rfc1483Vci и установить нужное значение.
После этого всего у меня модем заработал. Вот, через него сейчас и пишу

суббота, августа 06, 2005

"Плагин" для ИЕ

Хочет работодатель некое средство для сохранения страницы из браузера в точно заданное место. Странное желание, вообще-то - с третьего раза мартышку можно научить это делать, а сотрудника университета, способного эту страницу редактировать, научить не берутся...

Два дня искал информацию, как же, всё таки, написать плагин к ИЕ, чтоб это сохранение выполнить. Причём писать, желательно, на C# (ну, не люблю на плюсах, не нравится в кишках ковыряться). Чего-то нарыл, каких-то нескладных примеров.

Попытался соорудить ничего не делающий, с простым приветом плагин - дык, добился, что ИЕ падал сразу при запуске. Еле отбился от этой заразы.
В итоге плюнул на все эти мученья и за два часа соорудил "спец-браузер", умеющий загрузить страницу и сохранить её в файл, полный путь к которому указан в конфиге.

Выглядит как настоящий, да и действует, вообще-то.
Думаю, сгодится.

В принципе, можно будет со временем подумать о сооружении собственных браузеров такого типа - задать ему нужную функциональность, отбросив ненужное. Ещё бы разобраться, кто нужный, кто нет...

Давно не брал я в руки шашек...

Статейками, что ли, поразвлекаться, пока лето и жарко?

  • Про программирование AddIn'ов для Офиса.
  • Про web-парты кой-чего можно.
  • Ещё разное, чего в голову придёт.

Ожидайте, скоро будет!

пятница, августа 05, 2005

Пост из Ворда

с картинками и объектами - фокус не удался :-(
Из Outlook'а - практически так же.


Всё это накалякано в Word’е