суббота, 12 декабря 2009 г.

Прекрасная статья о том как упаковывать dll в один exe файл.

Single Assembly Deployment of Managed and Unmanaged Code

В кратце:

Добавляем нужную dll сборку как emebeded resource. Затем в статическом конструкторе класса, где она нужна (у меня это статический класс оборачивающий функции этой dll) прописываем вызов следующего метода:

namespace MyLib
{
public class MyClass
{
static MyClass()
{
ResourceExtractor.ExtractResourceToFile("MyLib.ManagedService.dll", "managedservice.dll");
ResourceExtractor.ExtractResourceToFile("MyLib.UnmanagedService.dll", "unmanagedservice.dll");
}

...

А это собственно реализация экстрактора:

public static class ResourceExtractor
{
public static void ExtractResourceToFile(string resourceName, string filename)
{
if (!System.IO.File.Exists(filename))
using (System.IO.Stream s = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Create))
{
byte[] b = new byte[s.Length];
s.Read(b, 0, b.Length);
fs.Write(b, 0, b.Length);
}
}
}

воскресенье, 9 августа 2009 г.

Танцы с бубнами.

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

Вот например кусок XAML, который мучал меня почти сутки



Если попытаться записать ему DataContext из CodeBehind, вот так:

MainChart.DataContext = Sale.Data;

то можно поймать совершенно изумительное ВэллНоун исключение:
...................................................
.................................
................

Вот так всегда. Даже попытка повторить его не удалась. Спрашивается, с чем я боролся то сутки? Танцы с бубнами, да и только...

В общем исключение было следующим: "Collection was modified; enumeration operation may not execute". Как я его заборол не понимаю до сих пор. Код, вроде как, тот же. Раньше не работал, теперь работает.

Возможно нужно было убрать установку DataContext из шаблонов в XAML и все. Еще один вариант - необходимо явно указывать Binding на родительские элементы. А те в свою очередь необходимо инициализировать из XAML каким-то начальным значением. Что-то из этого работает.

среда, 29 июля 2009 г.

Странный баг в .Net Silverlight RIA Services

Портируя Silverlight приложение на .Net RIA Services столкнулся с неприятным багом, который сейчас и попробую описать.

Имеется некий метод TotalDueByRegionId который принимает в качестве параметра с именем inputName строку ( раньше принимал число, но баг повторяется независимо от этого ).
И вот необходимо вызвать его из XAML кода контрола, что я и делаю следующим образом, пытаясь передать ему параметр:











Запускаем код и отлавливаем в вызов TotalDueByRegionId в сгенерированом коде:



В этом месте инструкция по адресу 03Bh передает значение в переменную this._value



Следующая инструкция устанавливает эту же переменную в null:



Дизасемблер IL кажет нам следующие:


Что явно не вяжется с тем, что происходит в реальности. Я в тупике. Как жить дальше?

UPD: Запостил на официальный форум Silverlight: http://silverlight.net/forums/p/115386/260071.aspx#260071

UPD 2: Решение: Когда необходимо просто передать параметр в запрос - надо использовать тип parameter вместо controlparameter. Controlparameter позволяет забаиндиться к свойствам других контролов. (Надо меньше тупить... Надо меньше тупить... и чаще отдыхать)

пятница, 22 мая 2009 г.

У меня программерская проблема. Некоторые вещи очень медленно компиляться. И за время компиляции я успеваю зачитатьс чьим нибудь блогом.

вторник, 28 апреля 2009 г.

Сейчас открою америку. Если не очень долго но упорно и не отдыхая делать одно дело - скучно становиться чрезвычайно быстро. Очень быстро....

пятница, 17 апреля 2009 г.

Javascript функция рекурсивного обхода DOM

Пока я с красными глазами искал как исправить баг в IE из прошлого поста. Я написал весьма полезную функцию подписывающую все подписывающиеся потомки заданного элемента на событие вызывающие alert. И хотя существует мнение, что дебажить код алертами плохо - эта возможность меня спасла, от разрыва мозга, как минимум.

function resetinputs(node) {
var oNode = node;
if (!oNode.length) {
try {
if (oNode.tagName == "IMG" || oNode.tagName == "MAP" || oNode.tagName == "AREA") { alert(oNode.tagName + "-|-" + oNode.id); };
if (oNode.Id == "ChartArea1") { oNode.style.opacity = ".5"; };
}
catch (dfr) { };
var curch = oNode;
try {
curch.onmouseup = function(evnt) {
var n = 1;
alert(this.tagName + " -|- " + this.id);
var z = 25;
};
} catch (eval) { };
if (oNode.childNodes) {
curch = oNode.childNodes;
for (var n = 0; n < curch.length; n++) resetinputs(curch[n]);
}
}
else {
curch = oNode.childNodes;
for (var i = 0; i < curch.length; i++) { resetinputs(curch[i]) };
}
return 1;
}

События Javascript на прозрачных элементах в IE 7 (Internet Explorer 7)

Мерзкий, гадкий, подлый осёл не дает перехватывать события на элементах страницы для которых стоит свойство background-color:transparent. У меня ушло немеряно времени что-бы отучить его от этого поведения, и заставить поймать мое событие.

Хак:

//Panel - это мой div
//Проверяем, действительно ли это IE7
if((document.all && !window.opera && window.XMLHttpRequest) ? true : false) {
//Делаем его мой див непрозрачным, ибо только непрозрачные контролы ловят события.
Panel.style.backgroundColor = "gray";
//И делаем его прозрачным снова.
Panel.style.filter = "alpha(opacity = 0)";
}


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

/*IE HACK. It takes more than 40 hours for me.*/
if((document.all && !window.opera && window.XMLHttpRequest) ? true : false) {
Panel.style.background = "url(bogus)";
}


Это решение найдено здесь