Jeśli zajmujesz się na poważnie pisaniem aplikacji na Windows Phone i często korzystasz z emulatora, to jest jedna opcja, która może ci pomóc w debugowaniu. Otóż emulator wyświetla logi na konsoli! Tak, korzysta ze standardowej konsoli w Windows. Domyślnie jest ona niestety ukryta. Brakuje menu, aby ją pokazać, zatem pozostaje tylko ustawienie magicznej wartości w rejestrze:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\XDE]
"EnableConsole"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\XDE]
"EnableConsole"=dword:00000001
Miłego podglądania!
d561cf61-6f73-4135-8c98-c21b051535d9|0|.0
Jakby tu zabezpieczyć swoje programy .NET-owe?
Szukałem, szukałem i znalazłem – darmowy obfuscator Eazfuscator.NET. Mnogość funkcji oraz wsparcie dla wszystkich współczesnych wersji platformy Microsoft .NET stawia go moim zdaniem na równi z płatnymi wersjami wielu innych firm znanych na rynku. Jedyne, czego życzyłbym sobie jeszcze w tym zestawie, to wsparcie dla Mono (chociaż samej manipulacji metadanymi), ale i tak duże wrażenie robi zaangażowanie autora w ten projekt przez tyle lat!
Życzę dalszej i równie dużej motywacji.
dea6c299-9ca0-4049-825f-2a9e9421419a|1|5.0
Testowanie - niestety temat zapomniany i zupełnie zignorowany przez twórców Windows Phone 7. Jakoś w głowie mi się nie mieści, że premiera telefonu odbyła się trzy miesiące temu, po raz pierwszy telefon pokazano światu w marcu 2010 i do dzisiejszego dnia nie doczekał się od oficjalnego frameworka testowego zintegrowanego z Visual Studio. Aż jestem ciekaw, jakim cudem tak dobrze go przetestowali i czy w ogóle zamierzają coś w tę stronę ruszyć. Bo widzę, nawet po kursie na virtualstudy.pl, że dużo ludzi interesuje się dużo bardziej cyklem życia aplikacji, niż prowadzeniem dobrego projektu na tej platformie (nie obrażając nikogo oczywiście).
Na samym początku wyjaśnię zatem, że oczywiście chodzi nam o pisanie testów, do których już przywykliśmy – czy to używając MS Unit Testing Framework, czy NUnit, używając atrybuty, które znamy i które nie sprawiają nam kłopotu oraz całego tego podejścia.
Tak, czy inaczej, błądząc po Internecie i marnując kolejne godziny możemy znaleźć garść przydatnych materiałów, które pozwolą uzbroić nas w środowisko do zabawy. Podejrzewam, że większość nie ma za dużo czasu, zatem przejdźmy od razu do meritum. Polecam zatem przestudiowanie przynajmniej:
- Wystąpienia Jeffa Wilcoxa na MIX2010 o testowaniu Silverlight3 i Silverlight4. Co ciekawe, jest on członkiem zespołu Silverlight (tworzącego między innymi Silverlight Toolkit) i pokazuje on tam między innymi swój autorski projekt. Doprawdy, podziwiam takich ludzi. Ale ciągle daje mi do myślenia, dlaczego Microsoft nie wspiera tego aktywniej (albo samemu?).
- Najnowszą wersję bibliotek, które trzeba dołączyć do projektu automatycznego testowania (o czym za chwilkę) znajdziemy na jego blogu. Dla potomności skopiowałem to również tutaj. Niestety jest to wersja z maja 2010, a mamy ostatni dzień grudnia i choć dzisiaj działa, to ciekawe jak będzie w niedalekiej przyszłości. Kontaktowałem się z Jeffem i obiecał rzucić okiem (popatrzeć na problemy, które mu zgłosiłem) i wypuścić nową wersję niedługo. Wszyscy jednak wiemy, jak to jest z wolnym czasem… no jest wolny ;)
Na koniec zostawiłem sobie zbudowanie aplikacji testowej. Oryginalny post, na którym bazuję znaleźć można tutaj. Jednak jak dla mnie jest on nieco przekombinowany. W skrócie mówi on o tym, że:
- Trzeba już mieć zainstalowane narzędzia do pracy z Windows Phone 7.
- Utworzyć najzwyklejszy projekt Silverlight3 dla Windows Phone 7.
- Dodać referencje do bibliotek Jeffa.
- Usunąć wszystkie strony aplikacji, gdyż to framework będzie je tworzył sam (za chwilkę).
- Zmodyfikować konstruktor aplikacji App() tak, aby oprócz monitorowania wyjątków, ustawiał odpowiednio widok (wszystko inne należy skasować z konstruktora):
this.RootVisual = UnitTestSystem.CreateTestPage();
-
I najważniejsze – CreateTestPage(), posiada też wersję, która przyjmuje dodatkowe opcje konfiguracji (UnitTestSettings). Wśród nich jest między innymi lista assembly, które mają być przeszukiwane w celu lokalizacji testów. Dodajemy do niej oczywiście wszystkie, które nas interesują. Po co? No ja osobiście wolę oddzielić same testy, od aplikacji, która je odpala. Mimo wszystko testy można użyć jeszcze gdzieś indziej, a tej aplikacji to już nie zawsze.
Wesołego TDD!
f75022c6-ddc0-408a-8eb0-f80d7c5ce79b|1|1.0
Sam temat nie powinien być nieznany. Atrybuty to od takie dodatkowe adnotacje w kodzie, które możemy “przypiąć” do klas, metod, pól (itd.), które nadają im bardziej mistyczne własności, objawiające się już dalej podczas działania samej aplikacji. Ot, po prostu gdzieś później sami będziemy sprawdzać, czy dana klasa, pole czy metoda jest naznaczona wykonywać dla niej specjalny kod, który jest ukryty pod ‘if’ dla typowych elementów.
Jednakże te ‘systemowe’ atrybuty, które oferuje platforma czy kompilator .NET potrafią coś więcej. Dziś pokażę wybrane atrybuty .NET, które według mnie zasługują na szerszy rozgłos i użycie. Niejednokrotnie znajomość ich ułatwiła mi pracę, zatem mam nadzieję, że komuś jeszcze pomogą.
- InternalsVisibleTo – sprawia, że bez ujawniania chronionych klas, “zaprzyjaźniony” tym atrybutem projekt testów jednostkowych (unit test) będzie widział wszystko i mógł tworzyć bez problemu instancje tych klas.
- Conditional – pozwala wyrzucić z kodu te funkcje (ich definicje oraz wywołania), dla których wskazany warunek nie jest prawdziwy. Przydatne bardzo do logowania operacji w trybie ‘Debug’, które nie są nam potrzebne w trybie ‘Release’. Oczywiście funkcje muszą spełnić kilka warunków, ale to już odsyłam do dokumentacji.
- AllowPartiallyTrustedCallers – pozwalamy używać swojego kodu nie w pełni autorytatywnemu kodowi (np. ściągniętemu z Internetu, który nie ma pełni praw wykonania na lokalnej maszynie).
- TestClass / TestMethod – atrybuty używane w projektach testów od oznaczania pojedynczych testów. Głównie używane z Microsoft Testing Framework, jednakże z poziomu funkcjonalności API, posiada on komplementarne funkcje do NUnit, dzięki czemu przy użyciu kilku dyrektyw ‘using’ można te atrybuty przekształcić na identyczne z NUnit. Dzięki czemu nasz kod testuje się świetnie w systemie Window oraz na maszynach z Linuxem czy MacOS, gdzie dostępne jest Mono.
783e553a-5224-40cb-8745-18aba34ae2cf|1|5.0
Dzisiaj wystartował mój najnowszy projekt open-source, oparty o licencję Apache 2.0. Jest nim oczywiście .NET-owa biblioteka do zapisywania/odczytywania wiadomości w formacie JSON. Kod źródłowy oraz binaria znaleźć można na codeplex.com.
Zachęcam do zerknięcia na nią okiem z powodów takich jak:
- pełne wsparcie standardu JSON
- mały rozmiar plików wykonywalnych (~30kb)
- wsparcie dla .NET 2.0+, Compact Framework 2.0 oraz Mono.NET 2.6
- prostotę i wygodę użycia API
- wysokiej jakości kod, oparty o testy automatyczne!
42fd02be-a647-40a8-8933-f25ea1beb6da|0|.0
Kiedy budzisz się pewnego dnia i od początku coś ci się nie układa. Nie wiesz do końca, o co chodzi, ale niektóre rzeczy dwoją i troją ci się w oczach. To jeszcze nie dowód na to, żeby odstawić mocniejsze trunki! To po prostu Visual Studio 2010 ześwirowało!
U mnie wyglądało to tak, że nie działał Backspace, Control i inne specjalne klawisze, zaś sam interfejs prezentował się tak, że każdy element menu i paska narzędziowego był zduplikowany kilka razy w pozornie losowych miejscach:

Wyglądało to na swój sposób tragicznie. Istnieje niestety tylko jedna opcja, która pozwala przywrócić IDE to stanu poprzedniego. Wszystkie innej (tj. próba zresetowania ustawień w Tools->Import/Export Settings…, czy usunięcie katalogu VisualStudio z Moich Dokumentów) spełzły na niczym.
A oto przepis, który wszystko przywraca do normalności:
devenv.exe /ResetUserData
d9c47add-805c-43e0-b514-d69d2a371c22|1|5.0
Z radością donoszę, że konkurs organizowany razem z Wrocławską Grupą .NET doszedł do skutku. Rozpoczyna się on już dziś (choć konkretniej to wczoraj) - 15 czerwca 2010! Trwał będzie aż do 21 września 2010!
W konkursie do wygrania cenne nagrody - 3 imienne komercyjne licencje na użytkowanie najnowszej wersji PostSharp 2.0, których fundatorem jest Paweł Hofman (CodeTitans.pl). Dalsze szczegóły dostępne są na stronie organizatorów tutaj. Życzę sukcesów i dobrej zabawy!

41125011-375b-480b-905c-da269c83a113|0|.0
Visual Studio 2008 jako narzędzie developerskie dla programistów Windows (czytaj .NET i nie tylko) plasuje się na pierwszej pozycji. Jednak pod względem rozszerzania i dostosowywania plasuje się daleko w tyle za swoim największym konkurentem Eclipse. Prawdopodobnie dlatego też Microsoft zrezygnował z opłat licencyjnych, wymaganych przy pisaniu dodatków jeszcze przy pierwszej wersji Visual Studio 2008 SDK.
Dlatego też chciałem dzisiaj pokazać kilka przykładów, jak Visual Studio możemy dostosowywać do swoich potrzeb (z użyciem lub bez SDK):
- Korzystając z dostępnych w sieci narzędzi, zmieniamy aktualny motyw (theme) tak, aby nie raził i nie męczył wzroku. Milutki generator znajdziemy tutaj.
- Grzebiąc w rejestrach systemu możemy włączyć wskaźnik po prawej stronie tekstu tak, aby linie tekstu nie były zbyt długie. Wyróżniona 21-a kolumna zapewni nas, że pisząc tak krótkie linie, otworzymy pliki z kodem źródłowym nawet na najstarszej DOS-owej maszynie.
Uaktualniamy rejestr systemowy dodając następujący wpis typu tekstowego (string):
[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Text Editor]
Guides = RGB(128,0,0) 20
(dowolnie dobieramy kolor oraz po przecinku za liczbą 20 wpisujemy dodatkowe wartości, jeśli jeden przewodnik to za mało)

- Piszemy własny wizualizator danych.
Wizualizatory to to, co tygrysy lubią bardzo. Bardziej lubią chyba tylko pakiety (VS Packages), ale o tym za chwilę. Idea wizualizatorów polega na tym, iż pisząc własne programy często tworzymy własne struktury danych, które łatwiej przestawiałyby się graficznie. Podczas debugowania Visual Studio udostępnia nam zatem kopię wskazanego obiektu, który możemy własnoręcznie przetworzyć i pokazać na ekranie. Poniżej znajduje się przykład wizualizatora obiektów System.__ComObject z wyszczególnieniem interfejsów i metod implementowanych przez tego CRW (Callable Runtime Wrapper).
Oznaczone odpowiednimi atrybutami assembly wgrywamy do katalogu:
%MyDocuments%\Visual Studio 2008\Visualizers
- Kolejnym ciekawym rozszerzeniem jest możliwość dodawania własnych słów kluczowych, które zostaną rozpoznane w edytorze tekstu dla VisualC++. Dotyczy się to przede wszystkim plików z rozszerzeniami .h, .c, .cpp, jednak bardzo dobrze sprawdza się również po przypisaniu edytora Microsoft Visual C++ do rozszerzeń takich jak .asm, .cu, czy tym podobnych (Tools->Options->Text Editor->File Extensions).
W poniższym pliku umieszczamy nowe słowa kluczowe w kolejnych linijkach, a po ponownym uruchomieniu Visual Studio od razu zauważymy efekty:
c:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\usertype.dat
- Na sam koniec deser. Gdy wymienione powyżej przykłady nie spełniają naszych wymagań, to zwracamy się w stronę pisania własnych rozszerzeń z w pełni funkcjonalną logiką. Co chcielibyśmy tym uzyskać, ot np.: aby z poziomu Visual Studio uaktualniały się wpisy w narzędziach do zarządzania błędami (ticket'y w wybranym trackerze) lub po prostu potrzebujemy dokujące okienko narzędziowe, które ściąga nowinki ze świata, przekonując pracodawcę, że jednak dzielnie kodujemy. Piszemy wtedy własny dodatek add-in lub VS Package wykorzystując w pełni możliwości oferowane przez SDK.
Należą do nich m. in.:
- własne edytory (lub zmiana istniejących)
- okna narzędziowe (tool windows)
- pliki pomocy
- nowe języki programowania (wraz ze schematami budowania nowych projektów)
- nowe rodzaje projektów (bądź dodawanie funkcji do istniejących, tj.: .csproj)
- szablony i kreatorzy (templates & wizards)
- dostawców usług (dostawcy listy błędów, zadań)
Więcej informacji o pisaniu dodatków do Visual Studio zamieściłem w Samouczku.
Jako działający przykład posłużyć może autorski projekt TytanNET.
Wytrwałych odsyłam do bloga Sary Ford, która do niedawna jeszcze żywo publikowała nowinki w stylu Tips&Tricks o Visual Studio oraz była autorką kilku książek o podobnie brzmiącym tytule.
Jako książkę z tej tematyki polecam (czym prawdopodobnie zadziwię niektórych) Inside Visual Studio .NET 2003 (tak 2003!), gdyż ona najdokładniej omawia sposób pisania add-inów oraz interakcję z tego poziomu z edytorami, plikami projektu i kodem źródłowym.
Wesołego kodowania!
1c971d8d-1062-43ab-8282-3bfa1076168f|0|.0
Podczas pracy nad projektem i uruchomieniu statycznej analizy kodu w Visual Studio 2008 (Code Analysis 2008/FxCop) napotkałem bardzo intrygujący błąd:
CA0058 : The referenced assembly 'EnvDTE, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' could not be found. This assembly is required for analysis and was referenced by: 'MojProjekt.dll', 'VSLangProj.dll'.
Należy w tym miejscu oczywiście zaznaczyć, że faktycznie projekt jest zależny od wymienionej VSLangProj.dll oraz EnvDTE.dll. Tyle, że ta ostatnia jest dołączana w wersji 8.0. Cały kłopot w tym, że wymagana wersja 7.0.3300, nie istnieje nigdzie w systemie. Wpływu na VSLangProj nie mamy żadnego, bo pochodzi on z publicznego SDK do Visual Studio, a naszym zadaniem nie jest przecież ‘naprawa’ tej sytuacji, a analiza własnego kodu źródłowego!, zatrzymana grubiańsko przez niezgodność skompilowanych bibliotek kogoś innego. Dodatkowo projekt działa i jakoś potrafi się odnaleźć w run-time’ie. Magia.
Zmiana właściwości referencji tak, aby wyłączyć wymaganie ‘Specific Version’, nie przyniosła żadnego rezultatu. W sumie można powiedzieć, że logiczne, bo przecież EnvDTE 7.0.3300 wymagany jest pośrednio przez VSLangProj.
Rozwiązanie:
- Przejść do lokalizacji: %ProgramFiles(x86)%\Microsoft Visual Studio 9.0\Team Tools\Static Analysis\FxCop
- Otworzyć w edytorze tekstowym: FxCopCmd.exe.config
- Zmienić wartość ustawienia AssemblyReferenceResolveMode na StrongNameIgnoringVersion
Od tej pory komunikat o błędzie zniknie bezpowrotnie.
Na załączonym obrazku przestawiam, jakie są jeszcze inne dostępne opcje, jeśli ktoś kiedyś będzie potrzebował.
ae514089-4741-475d-b833-b18149006c0f|0|.0
Bardzo szybko okazuje się, że prosta operacja przygotowania e-maila w domyślnym kliencie pocztowym na platformie Windows urasta do rangi spędzenia całego wieczoru na przeglądaniu internetowych forów w poszukiwaniu pomocy… Mail ten był o tyle specyficzny, iż miał posiadać ustawione od razu wartości:
- w polu osoby odbiorcy
- w polu tytułu
- treść
- oraz być z załącznikiem.
Najprostsze rozwiązanie, jakie przychodzi na myśl to wykonać zwykłe otwarcie poniższego odnośnika:
mailto:receiver@mail.com?subject=Tytul&body=To jest specjalny email&attachment=/path/file.txt
Niestety, MS Outlook 2003 ma problem z dołączeniem załącznika. Ścieżka nie gra tu najmniejszej roli, opakowanie jej w apostrofy, zmiana slash na backslash itp. nie pomagają. Parametr ten jest po prostu ignorowany i jego błędne podanie może tylko spowodować pokazanie komunikatu błędu.
Inne dwa potencjalne rozwiązania to, uruchomienie pliku outlook.exe z odpowiednimi przełącznikami (dokumentacja), jednakże wymienione wartości nie mogą być podane razem. Dlaczego?.. ot takie zachowanie programu.
Ostateczne rozwiązanie wygląda zatem tak, że bez pomocy małego programu w C# i odwołania do VSTO (Visual Studio 2008 Tools for Office) się nie obejdzie. Jego utworzenie wygląda mniej, więcej tak:
- W ‘Add Reference…’ na zakładce COM wybieramy ‘Microsoft Outlook 11.0 Object Library’
- Dodajemy referencję do przestrzeni nazw:
using Microsoft.Office.Interop.Outlook;
- Tworzymy odpowiedni obiekt e-mail i wypełniamy go danymi programistycznie. UWAGA! Aby uniknąć pytania z systemu zabezpieczeń Outlook o próbie przeglądania książki adresowej zalecam dodanie załącznika jako pierwszą operację w pozycji startowej wiadomości.
_Application app = new Application();
_MailItem messageItem = app.CreateItem(OlItemType.olMailItem) as _MailItem;
if (messageItem != null)
{
Attachments attachments = messageItem.Attachments;
string sourceFile = @"path-to-attachment-file";
string displayName = "Hello.txt";
attachments.Add(sourceFile, OlAttachmentType.olByValue, 1, displayName);
messageItem.Subject = "Hello World";
messageItem.Body = "New email with attachment using VSTO - Visual C#";
messageItem.To = "receiver@mail.com";
messageItem.Display(false);
}
c13ecbd4-955b-41ca-b1c1-521a44b9f718|0|.0