Saturday, April 19, 2008

Деплой ASP.NET страниц под MOSS 2007

Краткая предыстория: До февраля текущего года деплой aspx страниц предлагалось делать вручную, т.е. считалось что разработчику необходимо создать Web Site, затем выкладывать его в папку LAYOUTS самого MOSS. Однако, с появлением экстеншна v1.1 подобные манипуляции, а, следовательно, и ряд проблем были решены.

Т.о, сперва необходимо установить Extension VSeWSS 1.1.

Вариант деплоя до выхода экстеншна весьма подробно описан здесь http://msdn2.microsoft.com/en-us/library/cc297200.aspx .

Перейдем ко второму способу деплоя страниц: теперь не нужно копировать файлы в каталоги MOSS, а достаточно грамотно создать проект. В студии после установки Extension for SharePoint version 1.1 появляется вкладка WSP View (View-> Other Windows -> WSP View). Она отражает ту структуру, которая будет выложена в MOSS. Выявлено два способа деплоя aspx страниц при установленном экстеншне: а. в качестве Template’а ; б. в качестве Feature (Module)

Создаем Empty Sharepoint Project, добавляем к нему New Item -> Template

В дальнейшем, создавая папки в темплэйте, нужно учитывать, что они будут ложиться в каталог C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE . Т.е. если мы хотим положить aspx в Layouts, необходимо создать папку Layouts в темплэйте и положить туда aspx. Сравнивая оба варианта деплоя (а и б) нужно отметить, что когда в проект добавляется в качестве Module, т.е. aspx страница, которая кладется в модуль выступает в роли фичи (feature), тогда страница кладется в сборку MOSS, собственно как и code behind. В случае, когда aspx кладется в MOSS как Tempate, она просто физически кладется в папку Layouts.

Итак, мы создали Template. ascx файлы в SharePoint обычно хранятся в папке ControlTemplates. Для того чтобы отдеить наши контролы, которые лягут в ControlTemplates после деплоя имеет смысл создать отдельную папку для проекта, в нашем случае – это Sample, там и хранится Wizard.asсx. Code behind имеет смысл складывать в отдельную папку в проекте и все что хранится в нем будет в дальнейшем находится в сборке и браться оттуда. (в нашем примере это - Controls\Wizard.ascx.cs).

Добавление Template’а:

Затем добавляем Reference на:

Microsoft.Sharepoint и

Microsoft.Sharepoint.Security

Теперь добавляем aspx страницу в проект: как уже говорил, она должна добавляться как feature, т.е. в проект добавляется Module, далее в Module.xml указывается виртуальный путь к странице.

Добавление Feature:




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

Содержимое Module.xml имеет следующий вид:

Параметр Url содержит виртуальный путь, по которому мы можем обратиться к странице, т.е. к Wiz.aspx после deploy solution можно получить доступ по пути http://win2003moss/SAMP/_sample/Wiz.aspx

Т.о. solution имеет следующий вид:



Содержимое проекта в том виде как он будет выложен в MOSS выглядит так:



При добавлении новой feature плагин к MSVC Extension for Shrepoint Services v 1.1 автоматически обновляет файлы управляющие деплоем проекта в MOSS, такие как manifest.xml и feature.xml, однако их можно отредактировать самим вручную, открыв из WSP View.

Примечание:

При деплое могут вознкнуть ошибки, такие как: подобная feature уже существует (SAMP), в этом случае имеет смысл в Pre-build event command line добавить следующее:

echo Deactivating feature PSStuffSchedule ...

set SPAdminTool=%CommonProgramFiles%\Microsoft Shared\web server

extensions\12\BIN\stsadm.exe

set TargetUrl=http://win2003moss

"%SPAdminTool%" -o deactivatefeature -name SAMP -url %TargetUrl%

echo Uninstalling feature PSStuffSchedule ...

"%SPAdminTool%" -o uninstallfeature -name SAMP –force

Тем самым происходит деактивация feature и ее удаление. По идее при деплое проекта это должно происходить автоматически, но мне приходилось не раз сталкиваться с подобной проблемой. (альтернативой Pre-build event command line может быть запуск bat-файла с этим же содержимым перед деплоем проекта).

Если возникают другие ошибки на подобии «Закрыт доступ к папке» и пр. – необходимо перегружать сервис World Wide Web Publishing, такова уж специфика MOSS.

Алелуя братья, успехов на moss поприще.


Thursday, December 20, 2007

Model View Controller

Для более подробного описания паттерна MVC, на базе которого построен CAB крутим педали сюда:
http://rsdn.ru/article/patterns/ModelViewPresenter.xml

Wednesday, December 19, 2007

Composite UI Application Block (CAB) and Smart Client Software Factory

Сперва парочку слов с чего я заинтересовался этой частью .Net'а.
Для меня данный раздел новый, а поскольку уже достаточно компаний которые идут в ногу с технологиямии используют оную решил я узнать что за зверь такой и с чем его едят.
Как всегда - все гениальное просто, и данная технология не исключение.Рассмотрим ее на примере.


CAB - это реализация шаблонов и концепций предназначеных для создания сложных desctop приложений, словом надстройка над Win Forms.Идея CAB заключается в жесткой модульности создаваемого приложения, т.е. создаются максимально независимые друг от друга модули и реализовывается рабочий процесс внутри приложения (intra-application workflow).Жесткая модульность предназначена для повторного использования кода, что есть жЫрный +.Оболочка (UI элементы) слабо связаны с самими составными частями приложения.

Существует всего 4 слона на которых держится САВ, если говорить о САВ сервисах:
1. Загрузчик модулей и сервисы перечисления модулей
2. Сервис Event Broker
3. Сервис аутентификации
4. Сервис сохранения состояния

При создании САВ проекта сперва необходимо создать САВ-модуль, кот имеет свою точку входа.Модули находся внутри собственной DLL. Модули не требуют прямых ссылок на них из проекта оболочки в Visual Studio и непосредственной привязки к исполняемому файлу. Они загружаются в период выполнения загрузчиком модулей.

CAB-приложения базируются на шаблоне MVP/MVC (Model-View-Presenter/Model-View-Controller), который состоит из 3 элементов:
1. Presenter
2. SmartPart
3. State

Сервисы подключаются по мере необходимости в соответствии с логикой приложения. Это позволяет разработчику динамически создавать новые экземпляры объектов или возвращать объекты, уже созданные внутри контейнера. Для CAB этот контейнер является рабочим элементом и одним из первых создается разработчиком модуля. Компоненты CAB, например клиентские сервисы и рабочие пространства, можно добавлять в контейнер явно с помощью AddNew:
_rootWorkItem.WorkItems.AddNew();
То же самое можно сделать через конфигурационный файл или декларативно:

[CreateNew]
public ShipNewOrderViewPresenter Presenter{
set {
_presenter = value;
_presenter.View = this;
}
}

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

[ServiceDependency]
public WorkItem WorkItem{
set {
_workItem = value;
}
}

Главное что пожалуй стоит усвоить, это то что ключевым компонентом является OBjectBuilder.С помощью Object Builder(не без помощи концепции Dependency Injection) можно создавать объекты какого-либо класса или возвращать существующие, если они подходят;сопоставлять свойства и методы с аттрибутами, которые вляют на создание и именование новго объекта; удобно удалять параметры из существующих обхектов,двигаясь обратно по цепочке операций.За включение сервисов в наш модуль отвечает Dependency Injection.

Для CAB-приложения характерен следующий порядок работы.
1. Пользователь дважды щелкает EXE-файл, отображающий оболочку.
2. Оболочка появляется на рабочем столе, загружает заданные CAB-сервисы, отображает UI-элементы и загружает все сконфигурированные модули.
3. По окончании загрузки каждый модуль добавляет по рабочему элементу в свой родительский элемент, чтобы управлять подприложением и выдавать запросы к рабочему элементу на показ его содержимого в поддерживаемом рабочем пространстве.
4. Когда пользователь выбирает какой-либо элемент меню, срабатывает соответствующая команда.
5. Обработчик команд реагирует на эту команду созданием дочернего рабочего элемента, который управляет другим подприложением и отображает его представления.6. Рабочий элемент отображает свое представление с помощью Smart Part.
7. Пользователь взаимодействует с этим интерфейсом, который в свою очередь обращается к контроллеру (или его презентатору).
8. Контроллер изменяет общие данные (состояние) и связывается с хостом, используя Event Broker.
9. Event Broker отправляет актуальную информацию (контекст) другим модулям или компонентам.

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

1. Создаем новое Windows Forms приложение.
2. Добавляем в проект следующие ссылки на сборки:

Microsoft.Practices.CompositeUI
Microsoft.Practices.CompositeUI.WinForms
Microsoft.Practices.ObjectBuilder

3. Затем создаем класс приложения, в котором определяется WorkItem
public class MyFirstCABApplication :
FormShellApplication{ }

4. Реализуем метод Main:
[STAThread]public static void Main(){
new MyFirstCABApplication.Run();
}

5. Перегрузим AfterShellCreated, и вызовем его базовую реализацию и инициализируйте интерфейса

protected override void AfterShellCreated(){
base.AfterShellCreated();
// Регистрируем узел расширения,

// в данном случае - File Menu
ToolStripMenuItem fileItem = (ToolStripMenuItem) Shell.MainMenuStrip.Items["File"]; MyWorkItem.UIExtensionSites.RegisterSite( "File", fileItem.DropDownItems);
// Создаем и добавляем элементы меню в узел File Menu
ToolStripMenuItem item = new ToolStripMenuItem("Show Customer"); MyWorkItem.UIExtensionSites["File"].Add(item);
// Добавляем обработчик события "щелчок" в элемент меню

// с именем ShowCustomer MyWorkItem.Commands["ShowCustomer"].AddInvoker(item, "Click");

}

6. Создаем Smart-Part. Вводим в проект пользовательский элемент управления и добавим ссылку на пространство имен Microsoft.Practices.CompositeUI.SmartParts.После этого, добвим в свой класс аттрибут SmartPart:
[SmartPart]public partial class CustomerSmartPart : UserControl{ ...}

7. Теперь впихнем обработчик команд и отобразим SamrtPart с помощью DeckWorkspace:
[CommandHandler("ShowCustomer")]
public void ShowCustomer(object sender, EventArgs e){
Form1 mainForm = new Form1();
CustomerSmartPart sp = MyWorkItem.Items.AddNew(); mainForm.deckWorkspace1.Show(sp);
// deckWorkspace1 — элемент управления,

// перенесенный на Form1
}

В окно инструментария (toolbox) можно добавить любое рабочее пространство CAB и перенести
его на проектируемую форму подобно обычному элементу управления.

Создание модуля и инициализатора

1. Создадим библиотеку классов или элементов управления.
2. Добавим ссылки: Microsoft.Practices.CompositeUI Microsoft.Practices.ObjectBuilder
3. Добавим в проект ModuleAttribute, чтобы другие модули могли идентифицировать этот модуль в коде.
4. Добавляем в свой файл AssemblyInfo.cs:[assembly: Microsoft.Practices.CompositeUI.Module("MyFirstModule")]
5. Создаем новый класс и наследуем его от Microsoft.Practices.CompositeUI.ModuleInit
Перегружаем AddServices, чтобы иметь возможность добавлять САВ-сервисы в период выполнения, и перегружаем Load для отображения любого UI.
6. Чтобы наш модуль мог загружаться, создадим XML файл ProfileCatalog.xml, который ссылается на наш новый DDL файл с модулем. Добавим этот XML файл в основной EXE проект.
7. Каталог профиля будет выглядеть так:


8. Добавим метод Load и реализуем его в своем новом классе ModuleInit. Создаем объект WorkItem в нашем модуле с использованием метода AddNew в контексте RootWorkItem. Затем вызываем метод Run нового объекта WorkItem. Итого, мы получаем рабочее пространство по имени и передаем это рабочее пространство методу Run. В данном примере целевым является пространство DeckWorkspace с именем deckWorkspace1:

public override void Load(){
base.Load();
MyWorkItem myWorkItem = RootWorkItem.WorkItems.AddNew();
myWorkItem.Run(parentWorkItem.Workspaces["deckWorkspace1"]);
}

9. Реализуем метод Run нашего класса MyWorkItem, чтобы запустить свой собственный код:
public void Run(IWorkspace deckWorkspace){
// Используйте любой Smart Part
IMyView view = this.Items.AddNew();
deckWorkspace.Show(view);
}


Tuesday, September 11, 2007

Marshalling details

Уф, ох уж эта х64 based ОС, многое там по другому в отличие от x86.
Вот, к примеру - маршаллинг, ошибы такие выдает https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=284215

А тут вот по этому делу полезная итнфа:
http://www.mindon.net/articles/gchandle.html

Monday, August 27, 2007

XenoCode and obfuscation | Protect your Code

http://www.ishodniki.ru/art/print.php?cat=1&id=448&show=net&pr=#t10

PS: You can't be sure on 100% that your code is secure from the others but you can try to protect.

Thursday, June 28, 2007

Delete a Service

Normally it should not be necessary to manually delete a service. Uninstalling an application should remove its associated service (if any).
However, should it be necessary to manually remove a service:
Run Regedit or regedt32.

Find the registry entry:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services
Find the service there and delete it.You may wish to look at the keys and see what files the service was using and perhaps delete them also. Note:
You will have to reboot before the list gets updated in server manager. I have had it pointed out that some programs are cunning and prevent you from removing their service easily.
(For example the spyware\malware called ‘Command Service’ - "cmdService".) These change the permissions to make it more difficult for you to delete them. For these you will have to right click on the ‘service’ in regedit (regedt32), go to permissions and grant the administrator full control before the service can be deleted.