czwartek, 30 lipca 2009

Direction: Modern application interface (How to prepare a modern GUI for classic WinForms application using controls for .NET from Telerik) [EN]

kick it on DotNetKicks.comShout it

Recently I had the opportunity to take a closer look at the package Telerik Premium Collection for .NET. This package consist of several independent products including: RadControls for ASP.NET AJAX, RadControls for WinForms, RadControls for WPF, RadControls for Silverlight, Telerik Reporting, Telerik OpenAccess ORM. In this article I am going to present the steps that I have done to prepare a new user interface for existing application that is based on standard solutions from WinForms platform for .NET and my goal is preparation of a new interface that is consistent with current trends. To achieve this goal, I am going to use RadControls for WinForms from Telerik.

Maciej Zbrzezny welcomes everybody on his blog: Programming and Technologies [EN]

My name is Maciej Zbrzezny, I am working in CAS company as a software developer and architect of CommServer family software. I am interested in real-time systems programming, communication systems and new technologies.

This blog is about:

  • programming  and software development (especially in C# on .NET platform)
  • new technologies
  • integration
  • OPC, OPC Unified Architecture (OPC UA)
  • other topics from time to time ;)

This is not the first post on this blog (as maybe it seems to be) however I want this post to be a kind of introduction to the blog content in English.

Most of the posts on this blog are in Polish language however I am going to publish some articles in English from time to time. I hope you will enjoy reading it.

For English readers I suggest to follow "English posts" label on this blog.

środa, 29 lipca 2009

Na blogu "Programowanie i Technologie" będzie również po angielsku [PL]

Jak pewnie część moich czytelników zauważyła ostatnio przy wpisach na moim blogu pojawiły się dwa nowe elementy: w tytule [PL] i w etykietach "Polish posts", chyba nietrudno się domyślić w związku z tym, że pojawią się dopiski [EN] i etykieta: "English posts".

Więc przyznaję, zmierzam do tego, że na moim blogu będą pojawiały się również teksty w języku angielskim, postaram się jednak, by nie prowadziło to zbytniego zamieszania. Mam nadzieję, że w ten sposób nie zrażę do siebie moich aktualnych czytelników, a może zyskam następnych. Chciałbym również poinformować, że nadal dominującym językiem bloga, będzie język polski.

Zapraszam do dalszej lektury bloga.

Windows Logo Toolkit w wersji Beta [PL]

Jakiś czas temu na blogu "Only Human | Devoted to technology v.2.0" można było przeczytać na temat wymagań dla certyfikatu Windows 7 Logo, czyli co musi spełniać aplikacja, aby mogła być uznana (i certyfikowana) jako zgodna z Windows 7. Ja w tym wpisie chciałbym wtrącić swoje trzy grosze do tego tematu i zwrócić uwagę na narzędzie Windows Logo Toolkit.

Oprogramowanie to służy do weryfikacji zgodności aplikacji z wymaganiami loga "Compatible with Windows 7". Ostatnio stało się ono dostępne w wersji Beta, czyli już teraz można przetestować swoją aplikacje pod względem wymagań logo i wygenerować raport dotyczący państwa aplikacji. Według informacji ze stron Microsoftu, wraz z udostępnieniem wersji beta narzędzia do testowania uruchomiona została możliwość ubiegania się o logo "Compatible with Windows 7" na podstawie wygenerowanego raportu.

Microsoft uruchomił na swoich stronach (w MSDN'ie) tzw. centrum kompatybilności, gdzie można znaleźć informacje na temat programu certyfikacyjnego: http://msdn.microsoft.com/pl-pl/dd723617.aspx.

Narzędzie "Windows Logo Toolkit" jest natomiast do pobrania z witryny Microsoft Connect: http://connect.microsoft.com/site/sitehome.aspx?SiteID=831.

Warto również obejrzeć filmik prezentujący opisywane narzędzie i pokazujący jakie kroki należy wykonać, by przetestować oprogramowanie: http://co1piltwb.partners.extranet.microsoft.com/mcoeredir/mcoeredirect.aspx?linkId=12272132&s1=e072f7e9-727d-680d-1934-10787c93cbc6 lub http://wm.microsoft.com/ms/poland/developer/webcast.wmv (gdyby komuś któryś z linków nie zadziałał, trzeba spróbować kilkukrotnie - u mnie dopiero za którymś razem się film uruchomił).

Krótko mówiąc można uzyskać logo zgodności z Windows 7 jeszcze przed jego oficjalną premierą, a według zapewnień prezentera wspomnianego filmu, Ci którzy będą mogą otrzymać takie logo przed premierą mogą liczyć na zniżki.

wtorek, 28 lipca 2009

Bezpieczne przechowywanie pary kluczy algorytmu RSA na platformie .NET (przykłady w C#) [PL]

Klucze żadnego algorytmu kryptograficznego nie powinny być przechowywane w postaci otwartego tekstu, dlatego w celu ich przechowywania zostały opracowane odpowiednie kontenery (tzw. key containers). Kontenery kluczy są obszarami pamięci, przeznaczonymi do przechowywania kluczy kryptograficznych, którymi zarządzają dostawcy CSP (Crypto Service Provider); do ochrony zawartości kontenerów stosowane jest silne szyfrowanie i zabezpieczenia systemu operacyjnego.

.NET Framework automatycznie przymusza nas do wykorzystania tych kontenerów, np. przy wykorzystaniu niniejszego wywołania:

CspParameters csp = new CspParameters();
csp.KeyContainerName = "MyKeys";

W tym przypadku jeżeli kontener kluczy o tej nazwie istnieje, wtedy CSP wykorzystuje istniejące w nim klucze. Natomiast, gdy danego kontenera jeszcze nie ma, klucze są automatycznie generowane. Dlatego mylące może być twierdzenie, że powyższe dwie linie generują nowe klucze, a wielokrotne ich wywoływanie powoduje "otrzymanie" tych samych kluczy (przecież klucze zostały wygenerowane w momencie utworzenia kontenera, a później są już tylko z niego odczytywane).

Aby mieć pewność, że otrzymamy za każdym razem inną parę kluczy należy te klucze wykasować z danego kontenera, a może do tego zostać wykorzystana np. poniższa funkcja (jej źródło z MSDN):

public static void DeleteKeyFromContainer(string ContainerName)
{
    // Create the CspParameters object and set the key container
    // name used to store the RSA key pair.
    CspParameters cp = new CspParameters();
    cp.KeyContainerName = ContainerName;

    // Create a new instance of RSACryptoServiceProvider that accesses
    // the key container.
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

    // Delete the key entry in the container.
    rsa.PersistKeyInCsp = false;

    // Call Clear to release resources and delete the key from the container.
    rsa.Clear();

    Console.WriteLine("Key deleted.");
}

Więcej na temat zarządzania kluczami znaleźć można w MSDN, np. pod adresem: http://msdn.microsoft.com/en-us/library/tswxhw92.aspx, lub w książce: "C# - Księga przykładów" (z wyd. Microsoft Press) w rozdziale: "Bezpieczne zapamiętywanie klucza szyfrowania symetrycznego". Jeśli ktoś natomiast ma ochotę dowiedzieć się do czego można klucze wykorzystać, zapraszam do przeczytania mojego wcześniejszego posta: "Podpisywanie danych przy pomocy algorytmu RSA (przykłady w C#)."

poniedziałek, 27 lipca 2009

Blog C# .NET - podsumowanie tygodnia [PL]

Dziękuję wszystkim za zainteresowanie moją listą blogów C# .NET, po tygodniu istnienia tego posta GA pokazało mi takie statystyki:

  • 333 - Odsłony stron
  • 282 - Liczba niepowtarzalnych wyświetleń
  • 00:03:59 - Czas spędzony na stronie

Przyznam, że jak na tydzień, to w przypadku mojego bloga dużo, więc jeszcze raz dziękuję za zainteresowanie.

Zapraszam do dalszego komentowania i dodawania propozycji. Postaram się aktualizować listę "od czasu, do czasu".

Chciałbym jeszcze wrócić do kryterium, którego użyłem podczas tworzenia tej listy: w liście zostały uwzględnione tylko te blogi, które w ciągu ostatnich trzech miesięcy miały przynajmniej kilka wpisów. Oczywiście muszę jeszcze dodać, że w liście znalazły się tylko te blogi, które zdarza mi się odwiedzać (chociaż chętnie poznam nowe). Jeżeli chodzi, o portal Dotnetomaniak i ilość artykułów, które są na nim opublikowane (z różnych blogów), to nie chciałbym się z nim w żaden sposób porównywać. Tam źródeł jest na pewno więcej, ale czy wszystkie spełniają wymienione wcześniej kryterium, to już nie byłbym taki pewny.W każdym razie jeżeli ktoś uważa, że kogoś zabrakło, niech poda linka

Na koniec chciałbym dodać, że jeżeli komuś podoba się pomysł takiej listy, może niech doda do niej linka na swoim blogu:
Maciej Zbrzezny: Programowanie i Technologie: Blog C# .NET (czyli mini przewodnik po polskich blogach poświęconych C# i .NET) [PL]

poniedziałek, 20 lipca 2009

Snippet Compiler - gdy chcemy szybko i sprawnie wypróbować kod [PL]

Chyba każdy programista używa krótkich fragmentów kodu, który pokazuje zasadę działania jakiegoś elementu, klasy, algorytmu itp... Jednak uruchamianie dużego środowiska IDE (np. Visual Studio) tylko po to, by wypróbować jakiś kod to chyba strata czasu. Jest jednak dość użyteczna alternatywa: "Snippet Compiler".

Uruchamia on się w chwilę (sekundę?), a dzięki niemu można skompilować i uruchomić dowolny kod napisany w C#. Nadaje się on idealnie do wszelkiego rodzaju przykładów-snippetów, np. z blogów (w tym mojego ;), MSDN'u itp...

Można go pobrać spod adresu: http://www.sliver.com/dotnet/SnippetCompiler/

niedziela, 19 lipca 2009

Blog C# .NET (czyli mój mini przewodnik po polskich blogach poświęconych C# i .NET) [PL]

Przeglądałem ostatnio w Google Analytics źródła odwiedzin, a dokładniej zapytania wpisywane do wyszukiwarki, które powodują późniejsze odwiedziny mojego bloga i na pierwszym miejscu (po ok. półrocznym istnieniu mojego bloga) są słowa kluczowe: "blog c#". Do innych wysoko uplasowanych słów kluczowych zaliczyć można: "platforma .net", "blog .net c#", "c# .net blog", "programowanie", "platforma net framework", "blog opc c#", "c# samouczek", "c# artykuł", "c# przykłady", "c#". Chciałbym więc wyjść na przeciw moim czytelnikom i spróbować wskazać miejsca, gdzie można znaleźć informacje na temat C# i .NET w języku polskim. W moim post'cie skupię się przede wszystkim na blogach, a to dlatego, że słowo "blog" wystąpiło we wspomnianych wcześniej słowach kluczowych na pierwszym miejscu oraz dlatego, że już wcześniej Tomasz Smykowski w swoim blogu "Polishwords" napisał o: "Polskich stronach o programowaniu w C#" (http://polishwords.com.pl/blog/2008/polskie-strony-o-programowaniu-w-c/).

Moja lista i opisy mają charakter dość subiektywny, nie mam zamiaru oceniać, czy wskazywać najlepszego. Kolejność została ustalona w sposób nie zamierzony. Mam nadzieję, że nikt nie poczuje się urażony, zarówno tym co napisałem, jak i tym, że mogło go zabraknąć. Zachęcam do zostawiania komentarzy jeśli ktoś uważa, że coś należy uzupełnić lub kogoś dodać. Uwaga: w liście zostały uwzględnione tylko te blogi, które w ciągu ostatnich trzech miesięcy miały przynajmniej kilka wpisów.

A więc zacznijmy...

. jak .NET (http://www.maciejaniserowicz.com)

Blog Maciej Aniserowicza (Procent'a) poświęcony przede wszystkim technologi .NET. Ostatnia tematyka dotyczyła ASP.NET MVC, wykorzystania tzw. "mocków", Visual Studio 2010. Autor oprócz artykułów związanych z bezpośrednio z programowaniem zamiesza artykuły dot. trochę innych tematów, m.in aktualnych wydarzeń (związanych z platformą .NET), seria post'ów: "sko_dev_jarzenie" i inne. Blog aktualizowany jest dość regularnie (kilka postów w miesiącu).

.NET blog (http://pawlos.blogspot.com/)

Blog Pawła Łukasika (założyciela wortalu dotnetomaniak.pl) poświęcony głównie programowaniu (.NET, C#, WPF, WCF) i o dziedzinach pokrewnych. Czasami pojawiają się jeszcze informacje o aktualnych wydarzeniach związanych z .NET lub inne przemyślenia autora. Ostatnia tematyka dotyczyła przede wszystkim aktualnych wydarzeń oraz ciekawa i godna polecenia seria poświęconaprzygotowaniom autora do egzaminu 70-502 (WPF), w której kolejne posty poświęcone są wybranym zagadnieniom związanych z egzaminem 70-502 i WPF. Blog aktualizowany jest często (ok. kilkunastu wpisów miesięcznie).

.neting in the free world (http://zine.net.pl/blogs/gutek/default.aspx)

Blog Jakuba Gutkowskiego poświęcony przede wszystkim technologi .NET, bazom danych, i tematykom pokrewnych. Ostatnia tematyka dotyczyła przede wszystkim Visual 2010, baz danych, Code Contracts. Blog wyróżnia się dłuższymi niż zwykle (na innych blogach) artykułami. Blog aktualizowany jest dość regularnie (kilka postów w miesiącu).

Bartek Szafko (all of the bits and pieces) (http://bartekszafko.pl/)

Blog Bartka Szafko poświęcony jest programowaniu, instalatorom, i innym przemyśleniom autora. Godnym polecenia jest cykl artykułów poświęconych instalatorowi WiX.

Blog Michała Komorowskiego (http://michalkomorowski.blogspot.com/)

Jak sam autor pisze "blog o technologii .NET, programowaniu, języku C#, a czasem również o innych rzeczach...".

Blog o programowaniu w Silverlight, a także JAVA, .NET, Python, Symbian itp. (http://jacekciereszko.pl/)

Blog Jacka Ciereszko, tak jak głosi tytuł poświęcony jest przede wszystkim technologii Silverlight i narzędziom z tym związanych.

Dario-G - programista .NET (http://dario-g.com/)

Blog Dariusza Gila poświęcony przede wszystkim zagadnieniom związanym z .NET i aplikacjom Internetowym. Blog aktualizowany rzadko (ok 1-2 wpisy miesięcznie)

Only Human | Devoted to technology v2.0. Geek for geeks. Truly... (http://blogs.msdn.com/danieb/default.aspx)

Blog Daniela Biesiady poświęcony rozwiązaniom związanym z Microsoft. Na blogu pojawiają się artykuły dotyczących przede wszystkim aktualnościom, ale pojawiają się też artykuły związane z programowaniem w .NET (m.in ostatnio pojawiły się artykuły dot. F#, Visual Studio 2010). Blog jest bardzo często aktualizowany. Blog można polecić tym co chcą być na bieżąco z rozwiązaniami związanymi z Microsoft.

Grzegorz Rycaj: Visual Studio Team System | Rycu VS VSTS (http://grzegorz.rycaj.net/blog/)

Dość nowy (od 2009.06.13) blog Grzegorza Rycaja poświęcony przede wszystkim Visual Studio Team System.

Moje zmagania z .NET...i nie tylko (http://marcinborecki.spaces.live.com/)

Blog Marcina Boreckiego  pośiwoęcony wydarzeniom, narzędziom i programowaniu związanych z .NET. Blog wyróżniają dłuższe niz zwykle (na innych blogach) artykuły.Blog aktualizowany kilka razy w miesiącu.

MK.NET Live (http://marcinkruszynski.blogspot.com/)

Blog Marcina Kruszyńskiego poświęcony przede wszyskim Sliverlight i technologiom związnych z aplikacjami Internetowymi. Blog wyróżnia duża ilość filmów. Blog aktualizowany żadko (ok. dwóch post'ów na miesiąc).

Piotr Szczepanik - programowanie (.Net, C#, SQL), administracja, IT, blog IT: programowanie, administracja (http://blog.szczepanik.org/)

Autor w swoim blogu porusza tematy związane przede wszystkim z aplikacjami internetowymi.

Piotrosz: .NET's not dead  (http://www.piotrosz.aspnet.pl/)

Blog - notatnik Piotra Ludwiczuka, związany głównie z programowaniem w C# i ASP.NET. Ostatnio na blogu pojawiały się ciekawe i wartościowe artykuły związane z wzorcami projektowymi oraz transformatami (XSLT).

Xion.log (http://xion.org.pl/)

Blog Karola Kuczmarskiego (Xion) poświęcony programowaniu nie tylko związanemu z platformą .NET, ale też C/C++. Blog aktualizowany jest dość regularnie (kilka postów w miesiącu).

Programowanie i Technologie (czyli C#, .NET, OPC, OPC UA i inne) (http://maciej-progtech.blogspot.com/)

Mój (Macieja Zbrzezny) blog poświęcony zagadnieniom związanym programowaniem na platformie .NET i w języku C#, oraz innym technologiom, głównie związanym z automatyką przemysłową, OPC, OPC Unified Architecture, systemom czasu rzeczywistego. Staram się często aktualizować mojego bloga (kilka-kilkanaście razy w miesiącu).

Łukasz Sowa, o programowaniu w .NET i nie tylko (http://lukaszsowa.pl/)

Blog Łukasza Sowy poświęcony przede wszystkim wydarzeniom związanym z .NET, chociaż pojawiają się również artykuły o tematyce programistycznej. Blog aktualizowany rzadko, ok 1-2 wpisy miesięcznie.

Portal Społecznościowy - Grupa .NET, programowanie obiektowe, C#, msdn (http://www.grupanet.pcz.pl/community/Default.aspx)

Blog? Kamila Bosia poświęcony różnym aspektom związanym z .NET. Blog aktualizowany rzadko, ok 1-2 wpisy miesięcznie.

jakub.oboza@gmail.com (http://sharp.jogger.pl/)

Blog o różnej tematyce, chociaż pojawiają się też artykuły związane z .Net

Dotnetomaniak (http://dotnetomaniak.pl/)

Tym razem nie jest to blog, a miejsce gdzie możesz znaleźć najnowsze artykuły o technologii .NET znajdujących się na stronach polskiej społeczności. Tam również można znaleźć artykuły z wszystkich wymienionych wyżej blogów. Zapraszam!

Zine.net - dla pasjonatów, developerów .NET i nie tylko (http://zine.net.pl)

Strona agregująca blogi dotykające tematyki .NET. Znajdują się na niej artykuły z wielu powyżej wymienionych blogów.

Podsumowanie

Mam nadzieję, że spodobała wam się ta lista polskich blogów dotykających technologii .NET. Mam nadzieję, że nikt nie poczuł się urażony, że nie znalazł się na liście lub opisany został w inny niż chciałby sposób.

Gdyby ktoś uważał, że ma coś interesującego do dodania, to zapraszam do dodawania komentarzy. Proszę się nie przejmować gdyby komentarz nie pojawił się od razu, gdyż na moim blogu włączona jest opcja moderowania komentarzy, jednak obiecuję, że pojawi się każdy (związany z tematem) komentarz.

Zachęcam również do przeczytania artykułu: "Jak uczyć się C#?"

Na samym końcu chciałby zacytować motto twórców wortalu Dotnetomaniak: "Razem zbudujmy silną społeczność .NET w Polsce."

Historia zmian artykułu

  • 2009-07-19 - pierwsza wersja
  • 2009-07-27 - uwzględnia propozycje w komentarzach dodanych do 21 lipca 2009
  • 2010-04-18 - dodano link do artykułu: "Jak uczyć się C#?"

piątek, 17 lipca 2009

Książki o wzorcach projektowych [PL]

Już chyba dwa lata temu przeczytałem sobie książkę pod tytułem "C#. Wzorce projektowe". Książka w ciekawy sposób wprowadza w świat wzorców projektowych. Z pewnością nie jest ona skierowana do początkujących programistów, ale dzięki niej można sobie ukształtować myślenie w taki sposób, by osiągnąć rozwiązanie problemu programistycznego właśnie poprzez użycie odpowiedniego wzorca. Przecież nie ma potrzeby wymyślać koła od nowa, lepiej wykorzystać rozwiązanie, które już ktoś wcześniej wymyślił. Wszystkie przedstawione w książce wzorce projektowe zostały zilustrowane przykładami kodu w C# (!) oraz diagramami UML. Przedstawione w książce przykłady w ciekawy sposób pokazują zastosowanie każdego wzorca. W książce znalazły się takie informacje jak:

  • Podstawowe wiadomości o wzorcach projektowych
  • Interfejsy i klasy abstrakcyjne
  • Wzorce interfejsów
  • Wzorce odpowiedzialności
  • Wzorce konstrukcyjne
  • Wprowadzenie do operacji
  • Wzorce operacji
  • Wzorce rozszerzeń
  • Wzorce rozszerzające

Ostatnio natknąłem się na inną książkę o podobnej tematyce: "Head First Design Patterns". Książka ta jak każda z serii "Head First" przedstawia omawiane zagadnienia w specyficzny sposób ale chyba jest jeszcze jedna sprawa która ją odróżnia, to (chyba) trochę inne podejście do tematu, przez co trochę inna zawartość merytoryczna:

  • Cele stosowania wzorców projektowych
  • Założenia, na których opierają się wzorce projektowe
  • Najważniejsze i najczęściej wykorzystywane wzorce projektowe
  • Przechowywanie i prezentacja danych
  • Mechanizm RMI
  • Wzorzec MVC
  • Implementacja wzorców projektowych w aplikacjach

Piszę (chyba), bo książki jeszcze nie przeczytałem, ale mam nadzieję że mi się wkrótce uda (być może stanie się to możliwe np. za sprawą konkursu zaproponowanego na bloku Polishwords w post'cie pod tytułem: Głowa pierwsza: Wzorce Projektowe: http://polishwords.com.pl/blog/2009/glowa-pierwsza-wzorce-projektowe/

czwartek, 16 lipca 2009

"Application.UseWaitCursor = true" nie działa? [PL]

Czy zauważycie że "Application.UseWaitCursor = true;" nie działa tak jak by się tego oczekiwało - nie zmienia kursora na kursor oczekiwania (klepsydra, hourglass , kółko oczekiwania itp...)

Zawsze można spróbować inaczej:

Form form = Form.ActiveForm;
Cursor myPreviousCursor = form.Cursor;
form.Cursor = Cursors.WaitCursor;

// dlugotrwala czynnosc

form.Cursor = myPreviousCursor;

Lub

Cursor previousCursor = Cursor.Current;
Cursor.Current = Cursors.WaitCursor;

// dlugotrwala czynnosc

Cursor.Current = previousCursor;

Ogólnie pod tym adresem: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/18b8b65e-03cd-4a4f-9b7e-4e44ea5ac5df można znaleźć ciekawą wymianę zdań na ten temat. Można m.in. znaleźć następujący (ciekawy) kod:

using System;
using System.Windows.Forms;
public class HourGlass : IDisposable {
  public HourGlass() {
    Enabled = true;
  }
  public void Dispose() {
    Enabled = false;
  }
  public static bool Enabled {
    get { return Application.UseWaitCursor; }
    set {
      if (value == Application.UseWaitCursor) return;
      Application.UseWaitCursor = value;
      Form f = Form.ActiveForm;
      if (f != null && f.Handle != null)   // Send WM_SETCURSOR
        SendMessage(f.Handle, 0x20, f.Handle, (IntPtr)1);
    }
  }
  [System.Runtime.InteropServices.DllImport("user32.dll")]
  private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}

Używać można ten kod bezpośrednio poprzez ustawianie HourGlass.Enabled lub w sposób podobny do poniższego:

private void button1_Click(object sender, EventArgs e) {
  using (new HourGlass()) {
    // Do something that takes time...
    System.Threading.Thread.Sleep(2000);
  }
}

Oczywiście można spróbować pomieszać powyższe metody i np. z klasy HourGlass usunąć importowaną funkcję z biblioteki "user32.dll".

środa, 15 lipca 2009

Foreach element in enum (czyli jak przejrzeć wszystkie elementy Enum'a) [PL]

Tym razem temat jest bardzo prosty: "Jak wymienić (wyliczyć) wszystkie elementy typu wyliczeniowego (enum'a)?". Przyznam, że robiłem już to wiele razy, ale często musiałem się chwilę zastanowić: "jak to było?". Więc teraz w ramach ściągi dla siebie (a może komuś się to jeszcze przyda...)

Zakładamy, że mamy typ wyliczeniowy: MojEnum:

public enum MojEnum
{
 jeden,
 dwa,
 trzy,
 start
}

Jeśli chcemy np. wypisać wszystkie jego elementy to wystarczy wykorzystać następującą składnie: "foreach(MojEnum element in Enum.GetValues( typeof(MojEnum)) )", np.:

foreach(MojEnum element in Enum.GetValues( typeof(MojEnum)) )
{
 System.Console.WriteLine(element.ToString());
}

Prawda, że banalne?

Assembly.CodeBase vs. Assembly.Location [PL]

Chyba każdy kto operował ścieżkami plików pod .NET zauważył, że ścieżki te mogą występować w dwóch postaciach:

  • standardowej - typu: c:\katalog\plik
  • przypominającej URL, czyli file:////c:/katalog/plik

Różnicę widać właśnie porównując właściwość CodeBase i Location klasy Assembly. Zobaczmy jaki będzie wynik poniższego kodu:

Assembly myAssembly = Assembly.GetExecutingAssembly();
Console.WriteLine("CodeBase: {0}", myAssembly.CodeBase);
Console.WriteLine("Location: {0}", myAssembly.Location);

Efekt jest następujący:

  • CodeBase: file:///D:/CodeBaseLocation/CodeBaseLocation/bin/Debug/CodeBaseLocation.EXE
  • Location: D:\CodeBaseLocation\CodeBaseLocation\bin\Debug\CodeBaseLocation.exe

Ta sprawa była już klika razy na różnych stronach omawiana (m.in. tutaj: Suzanne Cook's .NET CLR Notes : Assembly.CodeBase vs. Assembly.Location). CodeBase to URL, który wskazuje na to gdzie można odnaleźć plik, podczas gdy Location wskazuje na miejsce skąd był załadowany. Np. jeśli assembly jest popbrane z Internetu (np. jako ClickOnce) jego CodeBase może się zaczynać od "http://", ale Location może się zaczynać od "C:\". Warto również wiedzieć, że CodeBase nie musi byś ustawione dla assembly pochodzących z GAC, natomiast Location będzie zawsze ustawiona dla tych assebly, które są załadowane z dysku.

Pytanie jednak jak przejść od jednego typu ścieżki do drugiego? (pomijając fakt, że nie zawsze jest to możliwe) Niestety nie udało mi się znaleźć gotowego rozwiązania, można to co prawda zrobić w kilku linijkach (np. tak jak pokazuje kod niżej) jednak wydaje mi się to trochę mało eleganckie. A może ktoś zna lepsze rozwiązanie?

if ( FileName.StartsWith( "file://" ) )
{
FileName = ( new System.Uri( FileName ) ).AbsolutePath;
FileName = FileName.Replace( "%20", " " );
FileName = FileName.Replace( "/", "\\" );
}

wtorek, 14 lipca 2009

Prosta obsługa Resource’ów aplikacji .NET (C#) [PL]

Obsługa zasobów aplikacji na platformie .NET jest bardzo prosta, zwykle wykorzystywany jest element typu "Resource", który można dodać do projektu, a następnie można przechowywać "w nim" różne inne elementy, jak: napisy, obrazki, ikony lub inne pliki. Wspomniany element typu Resource do obsługi zasobów, które są przez niego obsługiwane wykorzystuje klasę System.Resources.ResourceManager, dodatkowo tworzy on plik z kodem (np. w c#), który w sposób automatyczny udostępnia wybrane zasoby.

Czasami wygodniej jest wykorzystać inny sposób, w jaki można dodać zasób, by później go wykorzystać. Mowa tutaj o wybraniu szczególnej akcji dla pliku wchodzącego w skład projektu, a mianowicie ustawieniu właściwości "Build Action" na "Embedded Resource":

Jak jednak wykorzystać tak dodany do zasobów plik? Należy odwołać się do aktualnego assembly (Assembly.GetExecutingAssembly();), by następnie uzyskać dostęp do strumienia przy pomocy którego można odczytać dany plik z zasobów (myAssembly.GetManifestResourceStream( resname );).

Zobaczmy na poniższy przykład w którym wszystkie pliki, które w projekcie należały do katalogu "ExamplesFolder" i zostały ustawione jako "Embedded Resource" zostają skopiowane do katalogu "Moje dokumenty" bieżącego użytkownika do utworzonego katalogu "ExamplesFolder". Wykorzystana w przykładzie pomocnicza funkcja "CopyStream" ma za zadanie skopiować (binarnie) strumień wejściowy do wyjściowego).

namespace EmbeddedExampleApplication
{
class Program
{
/// <summary>
/// Copies the data between streams.
/// </summary>
/// <param name="inputStream">The input stream.</param>
/// <param name="outputStream">The output stream.</param>
public static void CopyStream(Stream inputStream, Stream outputStream)
{
byte[] buffer = new byte[512 * 1024]; // buffer creation - size 512 KB
int inputBytesCount;
while ((inputBytesCount = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
outputStream.Write(buffer, 0, inputBytesCount);
}
}

const string exampleFolder = "ExamplesFolder";

static void Main(string[] args)
{
//creating the directory
string filenamedirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), exampleFolder);
DirectoryInfo InstalationDirectoryInfo = new DirectoryInfo(filenamedirectory);
if (!(InstalationDirectoryInfo).Exists) InstalationDirectoryInfo.Create();
//copying of example files from assembly embedded resources
Assembly myAssembly = Assembly.GetExecutingAssembly();
//we will remove the namespace from file name
//the exampleFolder="ExamplesFolder" is the name of the folder in the solution
string currentNamespace = typeof(Program).Namespace + "." + exampleFolder + ".";
foreach (string resname in myAssembly.GetManifestResourceNames())
if (resname.Contains(exampleFolder))
{
Stream inputstream = myAssembly.GetManifestResourceStream(resname);
string filename = Path.Combine(filenamedirectory, resname.Replace(currentNamespace, ""));
Console.WriteLine(filename);
FileInfo filenameInfo = new FileInfo( filename );
if ( filenameInfo.Exists )
   filenameInfo.Delete();
using (Stream file = File.OpenWrite(filename))
{
   CopyStream(inputstream, file);
}
}
Console.ReadLine();
}
}
}

niedziela, 12 lipca 2009

Jak stworzyć i zainstalować serwis w Windows? [PL]

Przygotowanie serwisu dla systemu operacyjnego Windows jest przy użyciu Visual Studio (VS) bardzo proste. Wystarczy tylko utworzyć nowy projekt na podstawie szablonu "Windows Service" lub do istniejącego projektu dodać nowy element typu "Windows Service". Następnie należy zaimplementować metody:

  • OnStart, która wywoływana jest w momencie uruchamiania serwisu
  • OnStop, która wywoływana jest w momencie zatrzymywania serwisu

W tym miejscu należy jeszcze pamiętać, że nasze Assembly powinno być typu aplikacja, ale metoda "Main" najlepiej powinna wyglądać w sposób podobny do poniższego (oczywiście, jeżeli skorzystaliśmy wcześniej z odpowiedniego szablonu, to VS wykona wszystko za nas):

static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
  {
      new Service1()
  };
ServiceBase.Run( ServicesToRun );
}

W ten prosty sposób mamy przygotowaną aplikację, która może zostać wykorzystana jako serwis systemu Windows.

Pojawia się teraz pytanie: "Jak zainstalować taki serwis?"

Można to zrobić ręcznie, np. narzędziem installutil.exe, ale łatwiej chyba przygotować dodatkowy projekt instalacyjny (wystarczy wyklikać go przy pomocy VS z szablonu Setup Project), a do assembly naszej aplikacji-serwisu należy dodać odpowiedni instalator. W tym celu wybieramy z menu kontekstowego komponentu serwisu: "Add Installer":

W ten sposób zostaje dodany odpowiedni instalator do porjektu, który zawiera dwa komponenty: "Service Installer" i "Service Process Installer":

We właściwościach "Service Installer" ustawiamy nazwę serwisu i tryb uruchomienia:

Natomiast we właściwościach "Service Process Installer" ustawiamy konto, na którym serwis będzie uruchamiany ( w przypadku wybrania konta typu "konkretny użytkownik" instalator podczas instalacji zapyta się o nazwę użytkownika i hasło.)

Tak przygotowany serwis instalujemy przy pomocy stworzonego (drugiego projektu) typu "Setup" i możemy cieszyć się zinstalowanym serwisem w systemie Windows:

środa, 8 lipca 2009

Uwaga na return wewnątrz kontrukcji: try, catch, finally (czyli kiedy return nie powoduje opuszczenia funkcji)

Jedna z zasad dobrego programowania mówi: "Funkcja powinna mieć tylko jedną instrukcję return". Dzięki takiemu podejściu zawsze łatwo jest zlokalizować punkt wyjścia z funkcji, zwykle łatwiej zrozumieć napisany kod i w konsekwencji łatwiej go "utrzymywać" (i oczywiście zmieniać). Czasami jednak dużo łatwiej (lub krócej) można napisać kod funkcji, w której pojawi się wiele instrukcji return, dlatego często nie opieramy się takiej pokusie i takie funkcje tworzymy.

W tym krótkim post'cie zaprezentowany zostanie przykład, w którym analiza kodu funkcji z wieloma instrukcjami return może dla pewnych osób okazać się zaskakująca (mi zajęło pewną chwilę zanim zrozumiałem podobną do prezentowanej konstrukcję w większym oprogramowaniu).

Spójrzmy więc na poniższy kod (w komentarzu znajduje się też wynik działania):

using System;
namespace finally_and_return
{
  class Program
  {
    static void myFunction( bool throwException, bool earlyReturn )
    {
      try
      {
        if ( earlyReturn )
          return;
        if ( throwException )
          throw new Exception( "My Exception" );
      }
      catch ( Exception ex )
      {
        Console.WriteLine( "Exception: {0}",ex.Message );
      }
      finally
      {
        Console.WriteLine( "finally" );
      }
      Console.WriteLine( "end of myFunction" );
    }
    static void Main( string[] args )
    {
      Console.WriteLine( "--------------------------------------" );
      Console.WriteLine( "example 1: call myFunction(false,false )" );
      myFunction( false, false );
      Console.WriteLine( "--------------------------------------" );
      Console.WriteLine( "example 2: call myFunction(true,false )" );
      myFunction( true, false );
      Console.WriteLine( "--------------------------------------" );
      Console.WriteLine( "example 3: call myFunction(false,true )" );
      myFunction( false, true );
      Console.ReadLine();
//result:
//   
//--------------------------------------
//example 1: call myFunction(false,false )
//finally
//end of myFunction
//--------------------------------------
//example 2: call myFunction(true,false )
//Exception: My Exception
//finally
//end of myFunction
//--------------------------------------
//example 3: call myFunction(false,true )
//finally
    }
  }
}

Wynik przykładu 1 i 2 chyba dla każdego wydaje się oczywisty. W tym miejscu chciałbym zwrócić uwagę na przypadek trzeci (example 3), gdzie wewnątrz sekcji try wykonany zostanie return, ale ... nie powoduje to opuszczenia funkcji, gdyż musi zostać jeszcze wykonany obowiązkowy blok finally (i tylko on, a nie to co po nim nastąpi). Jest to oczywiście zgodne z zasadą koncepcji: try, catch, finally, w której blok finally ma zostać wykonany zawsze, nie zależnie od tego co wydarzy się w try. Przyznacie chyba jednak, że przy analizie takiego kodu można łatwo się pomylić...

środa, 1 lipca 2009

WinForms: Cross-thread operation not valid


Chyba każdy, kto pisał kiedykolwiek aplikacje wielowątkowe, które swoje wyniki prezentowały na kontrolkach WinForms spotkał się z następującym wyjątkiem:
System.InvalidOperationException occurred, Message="Cross-thread operation not valid: Control 'MainForm' accessed from a thread other than the thread it was created on.", Source="System.Windows.Forms"
Powyższy wyjątek pojawia się, gdy chcemy zmodyfikować zawartość kontrolki z innego wątku, niż ona została wytworzona. W prostszych słowach można powiedzieć, że innego wątku niż ten, który obsługuje okno. Rozwiązanie nie jest może skomplikowane, ale ponieważ musiałem je stosować już wiele razy postanowiłem sobie w tym post'cie przygotować pewnego rodzaju ściągę, a może przyda się to jeszcez komuś.
Otóż w funkcji, która modyfikuje zawartość kontrolki, należy sprawdzić, właściwość o nazwie InvokeRequired i jeżeli jest ona ustawiona na true, to mamy do czynienia z przypadkiem, że funkcję wywołał inny wątek, niż ten co obsługuje kontrolkę. Jeżeli tak jest, to musimy wykorzystać funkcję kontrolki: BeginInvoke, która spowoduje, że to co chcemy wykonać odbędzie się asynchronicznie w stosunku do wątku wywołującego oraz że zostanie, to wykonane w wątku obsługującym kontrolkę.
Poniższy przykład wykorzystuje opisywaną tu metodę i zamykanie okna odbywa się poprzez delegację, jeżeli zachodzi taka potrzeba (InvokeRequired).
    void Application_ShutdownRequest( object sender, EventArgs e )
    {
      if ( InvokeRequired )
      {
        BeginInvoke(new MethodInvoker(Close));
      }
      else
        this.Close();
    }

Posty powiązane / Related posts