<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-364616448054212690</atom:id><lastBuildDate>Tue, 31 Jan 2012 18:05:43 +0000</lastBuildDate><category>GIS</category><category>Visual Studio</category><category>refleksje</category><category>Team Foundation Server</category><category>społeczności</category><category>Velocity</category><category>cache</category><category>chmura obliczeniowa</category><category>terminologia</category><category>Code Camp</category><category>SQL Server</category><category>bazy danych</category><category>Raven DB</category><category>wydajność</category><category>praca w zespole</category><category>UI</category><category>VB.NET</category><category>interoperacyjność</category><category>programowanie</category><category>XAML</category><category>ASP.NET</category><category>różne</category><category>ESRI</category><category>Galaxy GT-I5700</category><category>raportowanie</category><category>Xml</category><category>PowerShell</category><category>Xsl</category><category>lokalizacja</category><category>bezpieczeństwo</category><category>WWF</category><category>Android</category><category>konferencja</category><category>narzędzia</category><category>optymalizacja</category><category>.NET od środka</category><category>Informix</category><category>wyszukiwarki</category><category>Londyn</category><category>Internet</category><category>IntelliTrace</category><category>cloud computing</category><category>CSS</category><category>synchronizacja</category><category>Polska</category><category>społeczeństwo</category><category>IIS</category><category>kariera zawodowa</category><category>blog</category><category>Google</category><category>teatr</category><category>C#</category><category>Team System</category><category>gry</category><category>IL</category><category>Xslt</category><category>globalizacja</category><category>COM/COM+</category><category>książki</category><category>dobre praktyki</category><category>rozrywka</category><category>ADO.NET Data Services</category><category>JavaScript</category><category>Html</category><category>WPF</category><category>.NET</category><title>Michał Komorowski</title><description>Blog o nowoczesnych technologiach i programowaniu, a czasem również o innych rzeczach...</description><link>http://www.michalkomorowski.com/</link><managingEditor>noreply@blogger.com (Michał Komorowski)</managingEditor><generator>Blogger</generator><openSearch:totalResults>160</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/BlogMichalaKomorowskiego" /><feedburner:info uri="blogmichalakomorowskiego" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-4046407546040336790</guid><pubDate>Sun, 22 Jan 2012 10:53:00 +0000</pubDate><atom:updated>2012-01-22T11:56:55.088+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">bazy danych</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">Raven DB</category><title>RavenDB (cz. 2) - podstawowe operacje na dokumentach</title><description>&lt;br/&gt;

&lt;div align="justify"&gt;

&lt;h4&gt;Wstęp&lt;/h4&gt;

W drugim poście poświęconym Raven DB opiszę jak wykonywać podstawowe operacje (zapisz/usuń/zmień) na dokumentach. Ale czym jest dokument? Nie wiem jaka jest formalna definicja ale ja na dokumenty patrzę po prostu jak na obiekty zapisane (zserializowane) w formacie JSON. Poniżej przykład takiego dokumentu z mojego &lt;i&gt;pet project&lt;/i&gt;, który odpowiada obiektowi klasy reprezentującej wyrażenie i jego tłumaczenia.

&lt;pre&gt;
{
  "Category": "Geografia",
  "Expression": "wioska",
  "Translations": [
    {
      "Language": "Language1",
      "Translation": "Dorf",
      "GoodAnswers": 0,
      "BadAnswers": 1,
      "WasLastAnswerGood": false
    },
    {
      "Language": "Language2",
      "Translation": "village",
      "GoodAnswers": 1,
      "BadAnswers": 0,
      "WasLastAnswerGood": true
    }
  ]
}
&lt;/pre&gt;

Klasa, której obiekty chcemy wrzucić do Raven DB może być zwykłym POCO z dokładnością do jednej rzeczy. Musi posiadać taką właściwość:

&lt;pre class="brush:csharp"&gt;
public int Id { get; set; }
&lt;/pre&gt;

To przykład konwencji. Jeśli chcemy zmienić sposób przechowywania identyfikatora, należy skorzystać z &lt;i&gt;DocumentStore.Conventions.FindIdentityProperty&lt;/i&gt;. Użyty przeze mnie &lt;i&gt;EmbeddableDocumentStore&lt;/i&gt; dziedziczy z &lt;i&gt;DocumentStore&lt;/i&gt;, a więc jeśli znudzi mi się &lt;i&gt;Id&lt;/i&gt; to zawsze mogę to zmienić.

&lt;br/&gt;&lt;br/&gt;

Jeśli chcemy aby Raven DB ignorował niektóre właściwości w czasie zapisywania obiektu to powinniśmy oznaczyć je atrybutem &lt;i&gt;Newtonsoft.Json.JsonIgnore&lt;/i&gt;, który działa w taki sam sposób jak &lt;i&gt;XmlIgnore&lt;/i&gt; dla &lt;i&gt;XmlSerializer&lt;/i&gt;.

&lt;h4&gt;Zapisz/Zmień&lt;/h4&gt;

Operację wstawienia nowego dokumentu do bazy lub aktualizacji już istniejącego wykonuję w taki sam prosty sposób np.:

&lt;pre class="brush: csharp"&gt;
public void Save(ExpressionEntity ex)
{
 using (var session = Store.OpenSession())
 {
  session.Store(ex);
  session.SaveChanges();
 }
}
&lt;/pre&gt;

Zaczynam, więc od otworzenia sesji pracy z RavenDB. Następnie przy pomocy metody &lt;i&gt;Store&lt;/i&gt; wrzucam do bazy nowy dokument lub aktualizuję już istniejący. Jak widać nie przejmuję się, którą operację właściwie wykonuję. Jeśli obiekt będzie miał pusty/zerowy &lt;i&gt;Id&lt;/i&gt; to zostanie utworzony nowy dokument, a właściwość &lt;i&gt;Id&lt;/i&gt; zostanie uaktualniona. Jeśli &lt;i&gt;Id&lt;/i&gt; zostanie wypełnione Raven DB spróbuje odszukać istniejący dokument i go uaktualnić. Jeśli nie znajdzie dokumentu o podanym identyfikatorze utworzy go. Metoda &lt;i&gt;SaveChanges&lt;/i&gt; to coś w rodzaju &lt;i&gt;Commit&lt;/i&gt;'a: wysyła zmiany do serwera.

&lt;h4&gt;Usuń&lt;/h4&gt;

Usuwanie dokumentów z bazy również jest bardzo proste np.:

&lt;pre class="brush: csharp"&gt;
public void Remove(ExpressionEntity ex)
{
 using (var session = Store.OpenSession())
 {
  session.Delete&amp;lt;ExpressionEntity&amp;gt;(session.Load&amp;lt;ExpressionEntity&amp;gt;(ex.Id));
  session.SaveChanges();
 }
}
&lt;/pre&gt;

Jak widać przed usunięciem ładuję obiekt z bazy na podstawie identyfikatora. Jest to potrzebne ponieważ inaczej dostaniemy błąd z informacją, że obiekt nie jest doczepiony do sesji (&lt;i&gt;is not associated with the session, cannot delete unknown entity instance&lt;/i&gt;). Nie znalazłem innego sposobu rozwiązania problemu.

&lt;h4&gt;Ważna uwaga&lt;/h4&gt;

Powyżej przedstawiłem dwie przykładowe metody &lt;i&gt;Save&lt;/i&gt; oraz &lt;i&gt;Remove&lt;/i&gt;, które odpowiednio tworzą/aktualizują jeden dokument oraz usuwają jeden dokument z bazy danych. W przypadku wykonywania operacji na wielu dokumentach takie podejście będzie zbyt kosztowne. Jeśli zachodzi potrzeba pracy z wieloma dokumentami to powinniśmy zrezygnować z takiego mikro zarządzania i jak najwięcej operacji wykonywać w ramach jednej sesji.

&lt;h4&gt;Podsumowanie&lt;/h4&gt;

Dzisiaj pokazałem jak wykonywać podstawowe operacje na dokumentach. Jak widać jest to bardzo proste. Właściwie nie musimy nic robić aby nakłonić nasze obiekty do współpracy z Raven DB. Nie potrzebujemy również mappera relacyjno-obiektowego. To jest właśnie to co bardzo mi się spodobało w Raven DB. 

&lt;br/&gt;&lt;br/&gt;

Definiuję sobie klasę, tworzę jej instancje i po prostu wrzucam je do bazy danych. Nie piszę komend &lt;i&gt;INSERT&lt;/i&gt;, &lt;i&gt;UPDATE&lt;/i&gt; lub &lt;i&gt;DELETE&lt;/i&gt;. Nie instaluję dodatkowych komponentów. Nie konfiguruję mapowań pomiędzy tabelami i obiektami. Nie definiuję schematu bazy danych. Jest prosto, szybko i przyjemnie czyli tak jak powinno być!

&lt;br/&gt;&lt;br/&gt;

Na koniec znowu podsumujmy co już mamy/umiemy:

&lt;ul&gt;

&lt;li&gt;Bazę Raven DB osadzoną w aplikacji hostującej.&lt;/li&gt;
&lt;li&gt;Kod inicjalizujący Raven DB.&lt;/li&gt;
&lt;li&gt;Dostęp do &lt;i&gt;Raven Studio&lt;/i&gt; i API &lt;i&gt;REST&lt;/i&gt;'owego.&lt;/li&gt;
&lt;li&gt;Obiekty POCO jakie mogą zostać umieszczone w Raven DB.&lt;/li&gt;
&lt;li&gt;Kod dodający/zmieniający/usuwający dokumenty.&lt;/li&gt;

&lt;/ul&gt;

&lt;/div&gt;

&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-4046407546040336790?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/_CgwU0Nx5U4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/_CgwU0Nx5U4/ravendb-cz-2-podstawowe-operacje-na.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>2</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2012/01/ravendb-cz-2-podstawowe-operacje-na.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-930390559157456663</guid><pubDate>Thu, 19 Jan 2012 09:43:00 +0000</pubDate><atom:updated>2012-01-19T10:53:10.450+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">bazy danych</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">Raven DB</category><title>RavenDB (cz. 1)</title><description>&lt;br/&gt;

&lt;div align="justify"&gt;

&lt;a href="http://ravendb.net/"&gt;Raven DB&lt;/a&gt; to dokumentowa baza danych, przedstawiciel trendu NoSQL, opracowana przez &lt;a href="http://ayende.com/blog"&gt;Ayende&lt;/a&gt; i jego zespół. Całkiem niedawno bo w październiku 2011 Ayende był zresztą w Polsce i opowiadał o swoim dziecku. Kilka miesięcy temu w jednym ze swoich &lt;i&gt;pet project&lt;/i&gt; postanowiłem zmienić technologię dostępu do danych i wybór padł właśnie na Raven DB.

&lt;h4&gt;Kilka słów wstępu&lt;/h4&gt;

Projekt ten to program &lt;i&gt;LanguageTrainer&lt;/i&gt; wspomagający naukę słówek. Pomysł jego napisania narodził się ponad rok temu kiedy "ponownie" rozpocząłem naukę języka niemieckiego. W sieci nie znalazłem programu, który spełniałby moje oczekiwania. Zdecydowałem więc, że napiszę coś szytego na miarę. Początkowo rozpoczęło się niewinnie: listę słówek i ich tłumaczeń trzymałem w pliku. Dokładniej mówiąc był to po prostu wynik serializacji XML'owej. Podejście to przestało się sprawdzać kiedy do głowy zaczęły mi przychodzić kolejne pomysły: A może dodać bardziej zaawansowane  wyszukiwanie, jakieś statystyki itd. 

&lt;br/&gt;&lt;br/&gt;

Początkowo pomyślałem o przejściu na bazę relacyjną, ale stwierdziłem, że tutaj nie nauczę się niczego nowego. Pomyślałem, że fajnie będzie wypróbować coś zupełnie nowego, z czym nie miałem jeszcze do czynienia, a ponieważ wcześniej czytałem trochę o Raven DB i wiedziałem, że ma .NET'owe API, wybrałem właśnie ją.

&lt;br/&gt;&lt;br/&gt;

Z bazą tą już trochę pracuję, z braku czasu niezbyt intensywnie, ale zebrałem już trochę doświadczeń i postanowiłem sie nimi podzielić. Planuję serię postów, w których opiszę jak pracuje się z Raven DB na przykładzie swojego &lt;i&gt;pet project&lt;/i&gt;. Nie będzie to jednak typowy tutorial omawiający wszystkie zagadnienia. Poruszę tylko te, z którymi miałem okazję się zapoznać.

&lt;h4&gt;Zaczynamy&lt;/h4&gt;

&lt;i&gt;LanguageTrainer&lt;/i&gt; to typowa aplikacja grubego klienta (WPF + MVVM). Nie chciałem jednak uzależniać się od połączenia z serwerem. Dlatego zdecydowałem się na hostowanie Raven DB w procesie aplikacji. Po ściągnięciu paczki z binariami na swoje potrzeby skopiowałem więc katalog &lt;i&gt;EmbeddedClient&lt;/i&gt;. W tym momencie zaznaczę jeszcze, że warstwę dostępu do danych mam ukrytą za dobrze zdefiniowanym interfejsem, a więc aplikacja nie wie z jakim źródłem danych pracuje. Poniżej fragment kodu z klasy implementującej ten interfejs, odpowiedzialny za zainicjowanie Raven DB. 

&lt;br/&gt;&lt;br/&gt;

&lt;pre class="brush:csharp"&gt;

public EmbeddableDocumentStore Store { get; private set; }

...

public void Init(string dir)
{
 Store = new EmbeddableDocumentStore
 {
  DataDirectory = dir,
  UseEmbeddedHttpServer = true,
 };

 Store.Initialize();
}
 
&lt;/pre&gt;
 
&lt;br/&gt;&lt;br/&gt;

Instancja &lt;i&gt;EmbeddableDocumentStore&lt;/i&gt; posłuży nam później do otwierania sesji pracy z Raven DB, wykonywania zapytań itd. W kodzie tym ustawiam tylko dwie właściwości. &lt;i&gt;DataDirectory&lt;/i&gt; wskazuje katalog roboczy, w którym Raven DB utworzy odpowiednią strukturę katalogów i gdzie będzie trzymał dane. Za pierwszym razem inicjalizacja zajmie więc trochę więcej czasu.

&lt;br/&gt;&lt;br/&gt;

Istotna jest też właściwość &lt;i&gt;UseEmbeddedHttpServer&lt;/i&gt;. Dzięki ustawieniu jej na &lt;i&gt;true&lt;/i&gt; mam dostęp do napisanej w Silverlight aplikacji &lt;i&gt;Raven Studio&lt;/i&gt; do zarządzania dokumentami oraz, co mniej ważne z mojej perspektywy, dostęp &lt;i&gt;REST&lt;/i&gt;'owy do dokumentów. Oczywiście ponieważ Raven DB jest hostowany przez mój program, aplikacja &lt;i&gt;Raven Studio&lt;/i&gt; będzie dostępna tylko wtedy, kiedy uruchomiony jest &lt;i&gt;LanguageTrainer&lt;/i&gt;.

&lt;br/&gt;&lt;br/&gt;

Numer portu z jakiego będzie korzystał serwer HTTP ustawiamy  w pliku konfiguracyjnym aplikacji dodając następujący wpis:

&lt;pre class="brush:xml"&gt;

&amp;lt;appSettings&amp;gt;
    &amp;lt;add key="Raven/Port" value="8888" /&amp;gt;
&amp;lt;/appSettings&amp;gt;

&lt;/pre&gt;

To jednak nie wszystko. Jeśli w tym momencie spróbujemy uruchomić &lt;i&gt;Raven Studio&lt;/i&gt; otrzymamy od serwera HTTP taki błąd:

&lt;br/&gt;&lt;br/&gt;

&lt;i&gt;Could not find file Raven.Studio.xap, which contains the Raven DB Studio functionality. Please copy the Raven.Studio.xap file to the base directory of RavenDB and try again.&lt;/i&gt;

&lt;br/&gt;&lt;br/&gt;

Plik &lt;i&gt;Raven.Studio.xap&lt;/i&gt; znajdziemy w dystrybucji Raven DB i musimy umieścić go w katalogu z jakiego uruchamiamy aplikację. Ja zrobiłem to w ten sposób, że dodałem go do projektu, &lt;i&gt;Build Action&lt;/i&gt; ustawiłem na &lt;i&gt;Content&lt;/i&gt;, a &lt;i&gt;Copy to Output Directory&lt;/i&gt; na &lt;i&gt;Copy if newer&lt;/i&gt;. Testowałem w przeglądarkach Chrome, Firefox oraz IE i działa.

&lt;h4&gt;Podsumowanie&lt;/h4&gt;

Tyle na dzisiaj. Podsumujmy  co już mamy/umiemy:

&lt;ul&gt;

&lt;li&gt;Bazę Raven DB osadzoną w aplikacji hostującej.&lt;/li&gt;
&lt;li&gt;Kod inicjalizujący Raven DB.&lt;/li&gt;
&lt;li&gt;Dostęp do &lt;i&gt;Raven Studio&lt;/i&gt; i API &lt;i&gt;REST&lt;/i&gt;'owego.&lt;/li&gt;

&lt;/ul&gt;

W następnej części opiszę jak wykonywać podstawowe operacji na dokumentach.

&lt;/div&gt;

&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-930390559157456663?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/cgc_ZvI0TtQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/cgc_ZvI0TtQ/raven-db-to-dokumentowa-baza-danych.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>1</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2012/01/raven-db-to-dokumentowa-baza-danych.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-5737008702180661605</guid><pubDate>Sat, 24 Dec 2011 10:11:00 +0000</pubDate><atom:updated>2011-12-24T13:47:05.980+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">różne</category><title>Życzenia świąteczne</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;
&lt;a href="http://4.bp.blogspot.com/-7zrDhT1EdR0/TvXHLiTyIbI/AAAAAAAAAfw/44gmdqrGwyc/s1600/Choinka2.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 300px; height: 400px;" src="http://4.bp.blogspot.com/-7zrDhT1EdR0/TvXHLiTyIbI/AAAAAAAAAfw/44gmdqrGwyc/s400/Choinka2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5689672705254760882" /&gt;&lt;/a&gt;
&lt;br/&gt;&lt;br/&gt;
Z okazji Świąt Bożego Narodzenia życzę czytelnikom i czytelniczkom wszystkiego dobrego, żeby najbliższe dni spędzili w wymarzony sobie sposób, z bliskimi sobie ludźmi, a w nowym roku pomyślności i wielu ciekawych wpisów na tym blogu :)
&lt;br/&gt;&lt;br/&gt;
Serdecznie pozdrawiam,
&lt;br/&gt;
Michał Komorowski
&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-5737008702180661605?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/Px7a0YMXgIo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/Px7a0YMXgIo/zyczenia-swiateczne.html</link><author>noreply@blogger.com (Michał Komorowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-7zrDhT1EdR0/TvXHLiTyIbI/AAAAAAAAAfw/44gmdqrGwyc/s72-c/Choinka2.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/12/zyczenia-swiateczne.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-2438863220683919261</guid><pubDate>Thu, 01 Dec 2011 20:46:00 +0000</pubDate><atom:updated>2011-12-03T17:08:08.227+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><title>Wczytywanie podzespołów do domeny aplikacyjnej</title><description>&lt;br/&gt;

&lt;div align="justify"&gt;

Platforma .NET, dzięki mechanizmowi refleksji, pozwala na dynamiczne wczytywanie do programu podzespołów (ang. &lt;i&gt;assembly&lt;/i&gt;). Pozwala to w łatwy sposób pisać rozszerzane przy pomocy pluginów aplikacje i na wiele innych rzeczy. Ostatnio potrzebowałem wykorzystać ten mechanizm do własnych celów. Aby zwiększyć bezpieczeństwo, postanowiłem ładować podzespoły do odzielnych domen aplikacyjnych.  W ten sposób, jeśli po załadowaniu podzespołu i wykonaniu jego kodu pojawi się błąd, główna domena aplikacyjna pozostaje nienaruszona.

&lt;br/&gt;&lt;br/&gt;

Użycie osobnej domeny aplikacyjnej przydaje się również kiedy chcemy wczytywać i usuwać załadowane &lt;i&gt;assembly&lt;/i&gt; z pamięci. Problem polega na tym, że po załadowaniu podzespołu do domeny nie ma możliwości aby go z niej usunąć. Można jednak osiągnąć podobny rezultat ładując podzespoły do oddzielnych "roboczych" domen, a potem skorzystać z metody &lt;i&gt;AppDomain.Unload&lt;/i&gt;, która usuwa z pamięci domenę i wszystkie wczytane do niej podzespoły. (To pewne uproszczenie. Jeśli &lt;i&gt;assembly&lt;/I&gt; zostało załadowane do kilku domen to zostanie usunięte dopiero jeśli usuniemy wszystkie domeny ją używające.)

&lt;br/&gt;&lt;br/&gt;

 Jak to zrobić? W sieci można znaleźć kilka podejść, ja użyłem w uproszczeniu następującego sposobu:

&lt;pre class="brush:csharp"&gt;
public static class SeperateDomainAssemblyLoader
{
  [Serializable]
  private class InternalLoader
  {
    public void LoadAndProcess(string assemblyPath)
    {
      Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);

      var assembly = Assembly.LoadFrom(assemblyPath);
      //...
    }
  }

  private static AppDomain _domain = AppDomain.CreateDomain("SeperateDomainAssemblyLoader");

  public static void LoadAndProcess(string assemblyPath)
  {
    InternalLoader internalLoader = (InternalLoader)(_domain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().Location, typeof(InternalLoader).FullName));
    internalLoader.LoadAndProcess(assemblyPath);
   }
}
&lt;/pre&gt;

i kod testujący:

&lt;pre class="brush:csharp"&gt;
...
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
SeperateDomainAssemblyLoader.LoadAndProcess(somePath);
...
&lt;/pre&gt;

Niestety ku mojemu zdziwieniu program wypisał na ekran dwa razy tą samą nazwę domeny. Jak to możliwe, przecież jak wół stoi, że instancja klasy &lt;i&gt;InternalLoader&lt;/i&gt; została stworzona w osobnej domenie. Uważni czytelnicy już pewnie widzą błąd. Ja też go znalazłem, ale chwilę zajęło mi uzmysłowienie sobie, co robię nie tak.

&lt;br/&gt;&lt;br/&gt;

Zapomniałem o tym, że obiekty pomiędzy domenami aplikacyjnymi przekazywana są domyślnie przez wartość. Co z tego, że utworzyłem obiekt w osobnej domenie, skoro i tak pracowałem z jego kopią. Jeśli &lt;i&gt;InternalLoader&lt;/i&gt; dziedziczyłby z &lt;i&gt;MarshalByRefObject&lt;/i&gt; to pracowałabym nie z prawdziwym obiektem ale z &lt;i&gt;proxy&lt;/i&gt; i wszystko byłoby dobrze. Poprawka jest więc bardzo prosta:

&lt;pre class="brush:csharp"&gt;
...
private class InternalLoader : MarshalByRefObject
{
  ...
}
...
&lt;/pre&gt;
&lt;/div&gt;

&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-2438863220683919261?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/wimmJ1-10qQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/wimmJ1-10qQ/wczytywanie-podzespoow-do-domeny.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/12/wczytywanie-podzespoow-do-domeny.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-4789047111271085099</guid><pubDate>Thu, 01 Dec 2011 20:45:00 +0000</pubDate><atom:updated>2011-12-01T21:48:23.704+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Team Foundation Server</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><title>Problem z półką</title><description>&lt;br/&gt;

&lt;div align="justify"&gt;

Jakiś czas temu próbując wykonać operację &lt;i&gt;merge&lt;/i&gt; w TFS napotkałem na bardzo irytujący problem pod tytułem:

&lt;br/&gt;&lt;br/&gt;

 &lt;i&gt;TF203015 The Item '' has an incompatible pending change.&lt;/i&gt; 
 
 &lt;br/&gt;&lt;br/&gt;
 
Nie robiłem nic bardzo skomplikowanego. Najpierw pobrałem do gałęzi A zmiany umieszczone na półce (ang. &lt;i&gt;shelve&lt;/i&gt;). Następnie, przy pomocy polecenia &lt;i&gt;merge&lt;/i&gt;, chciałem do nich dodać zmiany z &lt;i&gt;changeset&lt;/i&gt;'a z gałęzi B i w tym momencie pojawił się powyższy komunikat. Sprawdziłem też odwrotną kolejność czyli najpierw &lt;i&gt;merge&lt;/i&gt; z gałęzi B do A, a potem pobranie kodu z półki ale błąd również wystąpił. Innymi słowy, zamiast zgłosić konflikt i umożliwić jego rozwiązanie TFS wypiął się i rzucił błędem.

&lt;br/&gt;&lt;br/&gt;

Nie chciałem wykonywać "ręcznego" łączenia plików ponieważ to błędogenne i niewygodne. Zacząłem szukać rozwiązania i znalazłem &lt;a href="http://blogs.infosupport.com/the-how-and-why-behind-tf203015-lt-file-gt-has-an-incompatible-change-while-unshelving-a-shelve-set/"&gt;sposób&lt;/a&gt; na obejście problemu. Daleki od ideału, ale lepszy rydz niż nic. Postąpiłem w następujący sposób:

&lt;ul&gt;
&lt;li&gt;Zainstalowałem &lt;i&gt;Team Foundation Server Power Tools&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Najpierw wykonałem operację &lt;i&gt;merge&lt;/i&gt; z gałęzi B do gałęzi A.&lt;/li&gt;
&lt;li&gt;Uruchomiłem Visual Studio 2010 Command Prompt.&lt;/li&gt;
&lt;li&gt;Przeszedłem do katalogu z gałęzią A.&lt;/li&gt;
&lt;li&gt;Wpisałem komendę &lt;i&gt;tfpt unshelve&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Wybrałem swoja półkę.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Rozwiązałem konflikty.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;


Jak widać jeśli korzystamy z komendy &lt;i&gt;tfpt&lt;/i&gt; to zamiast otrzymać błąd dostaniemy listę wykrytych konfliktów i możliwość ich rozwiązania. Można? Ano można.

&lt;/div&gt;

&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-4789047111271085099?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/KCvCsHKYYNg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/KCvCsHKYYNg/problem-z-poka.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>1</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/12/problem-z-poka.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-5963271677847736667</guid><pubDate>Wed, 16 Nov 2011 11:15:00 +0000</pubDate><atom:updated>2011-11-16T12:28:38.994+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">narzędzia</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><title>Hawkeye</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

&lt;a href="http://hawkeye.codeplex.com/"&gt;Hawkeye .NET Runtime Object Editor&lt;/a&gt; to program, który znalazłem w sieci dobre dwa lata temu. W tym czasie wielokrotnie mi się przysłużył, a jest przydatny w szczególności tym, którzy pracują z technologią Windows Forms. W skrócie, pozwala modyfikować UI działającej aplikacji. Jego użycie jest proste. Wskazujemy myszką interesujący nas fragment aplikacji, a &lt;I&gt;Hawkeye&lt;/i&gt; oznacza wybraną kontrolkę przy pomocy czerwonej ramki i wyświetla listę właściwości i prywatnych pól klasy, których wartości możemy modyfikować. Jak by tego było mało, &lt;i&gt;Hawkeye&lt;/i&gt; pozwala również dynamicznie wywoływać metody dla wybranych obiektów.

&lt;br/&gt;&lt;br/&gt;

Zastanawiamy się jak nasza aplikacja będzie wyglądać z różowym tłem? Chcemy przesunąć na próbę kontrolkę o 2 piksele w prawo? A może chcemy nacisnąć przycisk, który jest nieaktywny? Te i inne rzeczy osiągamy zmieniając wartości odpowiednich właściwości, w tym przypadku odpowiednio: &lt;i&gt;BackColor&lt;/i&gt;, &lt;i&gt;Location&lt;/i&gt;, &lt;i&gt;Enabled&lt;/i&gt;. W trzecim wypadku możemy też wywołać dynamicznie metodę &lt;i&gt;PerformClick&lt;/i&gt;. Pozwala to w łatwy i przyjemny sposób zobaczyć, jak przy danych ustawieniach, będzie  w runtime'ie będzie wyglądała nasza aplikacja, bez potrzeby jej rekompilacji. 

&lt;br/&gt;&lt;br/&gt;

&lt;i&gt;Hawkeye&lt;/i&gt; pozwala również poruszać się w hierarchii kontrolek tworzących interfejs i sprawdzić kto jest rodzicem interesującej nas kontrolki. Podaje też pełną nazwę klasy dla aktualnie wybranego obiektu. Przydaje się to, kiedy pracujemy z dużą, skomplikowaną aplikacją i chcemy dowiedzieć się gdzie u licha znajduje się kod obsługujący aktualnie widoczną kontrolkę. Przykład z życia. Ostatnio kumpel potrzebował znaleźć kod odpowiedzialny za pewną część UI. W tym celu chciał wyświetlić designera dla interesującego go okna i na tej podstawie dojść do kontrolki. Niestety Visual Studio odmówiło posłuszeństwa i przy próbie wyświetlenia designera raportowało błąd. &lt;i&gt;Hawkeye&lt;/i&gt; rozwiązał problem w kilka minut.

&lt;br/&gt;&lt;br/&gt;

Uwaga! Na dzień dzisiejszy, na stronie programu znajdują się jego dwie wersje do pobrania. Jedna działa tylko z aplikacjami skompilowanymi na platformę .NET 4, a druga z aplikacjami skompilowanymi na starsze wersje platformy.
&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-5963271677847736667?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/orqjQTOxDhg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/orqjQTOxDhg/hawkeye.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>5</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/11/hawkeye.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-5468138265438935287</guid><pubDate>Fri, 28 Oct 2011 06:00:00 +0000</pubDate><atom:updated>2011-10-28T08:02:28.861+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">.NET od środka</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><title>Wiele usług w jednym procesie 2</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

W poście tym wrócę jeszcze do tematu uruchamiania kilku usług w jednym procesie. Otóż, ciekawe jest to, że można  konfigurować to zachowanie już po zainstalowaniu usługi. Służy do tego, i nie tylko tego, program wiersza poleceń o nazwie &lt;i&gt;sc&lt;/i&gt;. Poniżej przedstawiam przykład jego użycia. 

&lt;br/&gt;&lt;br/&gt;

Zacznijmy od pobrania konfiguracji usługi &lt;i&gt;ABC&lt;/i&gt; przy pomocy komendy &lt;i&gt;sc query ABC&lt;/i&gt;. Przykładowy wynik pokazałem poniżej.

&lt;pre&gt;
SERVICE_NAME: ABC
TYPE               : 20  WIN32_SHARE_PROCESS
STATE              : 1  STOPPED
  (NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)
WIN32_EXIT_CODE    : 1077       (0x435)
SERVICE_EXIT_CODE  : 0  (0x0)
CHECKPOINT         : 0x0
WAIT_HINT          : 0x0
&lt;/pre&gt;

Jak widać usługa &lt;i&gt;ABC&lt;/i&gt; może współdzielić proces z jakąś inną usługą. Efekt działania bardzo ładnie widać w menadżerze zadań. Jeśli uruchomimy usługi: &lt;i&gt;ABC&lt;/i&gt;  oraz &lt;i&gt;ABCDebug&lt;/i&gt; to menadżer zadań pokaże tylko jeden proces. 

&lt;br/&gt;&lt;br/&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-OH-tpHZXTY8/Tqe2iRTGjAI/AAAAAAAAAfY/xxLOQ5tpjwI/s1600/TaskMgr.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 27px;" src="http://1.bp.blogspot.com/-OH-tpHZXTY8/Tqe2iRTGjAI/AAAAAAAAAfY/xxLOQ5tpjwI/s400/TaskMgr.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5667699355944389634" /&gt;&lt;/a&gt;

&lt;br/&gt;&lt;br/&gt;

Aby to zmienić należy użyć komendy &lt;i&gt;sc config ABC type= own&lt;/i&gt;. Teraz, po uruchomieniu obu usług, menadżer zadań pokaże dwa procesy.

&lt;br/&gt;&lt;br/&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-FDXKtt7KDCs/Tqe2mEsMq-I/AAAAAAAAAfk/rowiKb7I8KE/s1600/TaskMgr2.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 41px;" src="http://2.bp.blogspot.com/-FDXKtt7KDCs/Tqe2mEsMq-I/AAAAAAAAAfk/rowiKb7I8KE/s400/TaskMgr2.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5667699421279464418" /&gt;&lt;/a&gt;

&lt;br/&gt;&lt;br/&gt;

Do stanu pierwotnego wracamy przy pomocy komendy &lt;i&gt;sc config ABC type= share&lt;/i&gt;. Warto zwrócić uwagę na jeszcze jedną rzecz. Spójrzmy na ten scenariusz.

&lt;ul&gt;
&lt;li&gt;Mamy dwie usługi współdzielące proces: &lt;i&gt;ABC&lt;/i&gt; oraz &lt;i&gt;ABCDebug.&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Uruchamiamy obie i menadżer zadań pokazuje jeden nowy proces: &lt;i&gt;WindowsService1.exe&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Zatrzymujemy usługę &lt;i&gt;ABC&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Usługa &lt;i&gt;ABCDebug&lt;/i&gt; nadal działa.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;sc config ABC type= own&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Uruchamiamy usługę &lt;i&gt;ABC&lt;/i&gt; i teraz menadżer zadań pokazuje dwa procesy &lt;i&gt;WindowsService1.exe&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Zatrzymujemy usługę &lt;i&gt;ABC&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;sc config ABC type= share&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Ponownie uruchamiamy usługę &lt;i&gt;ABC&lt;/i&gt; i menadżer zadań znowu pokazuje jeden proces &lt;i&gt;WindowsService1.exe&lt;/i&gt;.&lt;/li&gt;
&lt;/ul&gt;

Czyli w czasie kiedy zmienialiśmy konfigurację usługi &lt;i&gt;ABC&lt;/i&gt; usługa &lt;i&gt;ABCDebug&lt;/i&gt; cały czas działała i w niczym to nie przeszkadzało.

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-5468138265438935287?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/06tFBjhw4XM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/06tFBjhw4XM/wiele-usug-w-jednym-procesie-2.html</link><author>noreply@blogger.com (Michał Komorowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-OH-tpHZXTY8/Tqe2iRTGjAI/AAAAAAAAAfY/xxLOQ5tpjwI/s72-c/TaskMgr.JPG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/10/wiele-usug-w-jednym-procesie-2.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-8675063622058003776</guid><pubDate>Wed, 26 Oct 2011 20:18:00 +0000</pubDate><atom:updated>2011-10-26T22:18:40.352+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">.NET od środka</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><title>Wiele usług w jednym procesie</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

Istnieje kilka podejść do debugowania usług systemowych. Jeśli chcemy debugować już uruchomioną usługę to możemy skorzystać z opcji &lt;i&gt;Attach to process...&lt;/i&gt;. Sprawa jest trudniejsza jeśli chcemy podłączyć się do usługi w momencie jej uruchamiania. W takim wypadku można w kodzie usługi wywołać metodę &lt;i&gt;Debugger.Brake&lt;/i&gt;. Są też inne sposoby, na przykład sztuczne opóźnienie startu usługi, tak aby zdążyć się do niej podpiąć.

&lt;br/&gt;&lt;br/&gt;

Ostatnio poznałem nowe, bardzo ciekawe podejście. Polega ono na stworzeniu dodatkowej, pomocniczej "pustej" usługi i zainstalowaniu jej w odpowiedni sposób razem z właściwą usługą. Strukturę przykładowego projektu widać na poniższym rysunku. 

&lt;br/&gt;&lt;br/&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-Mvxy8h7t-pQ/TqcdoY56tPI/AAAAAAAAAfA/GO5AVryoki4/s1600/Project.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 169px; height: 145px;" src="http://1.bp.blogspot.com/-Mvxy8h7t-pQ/TqcdoY56tPI/AAAAAAAAAfA/GO5AVryoki4/s400/Project.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5667531235786405106" /&gt;&lt;/a&gt;

&lt;br/&gt;&lt;br/&gt;

Projekt musi również zawierać dwa instalatory (klasa &lt;i&gt;ServiceInstaller&lt;/i&gt;), po jednym dla każdej z usług.

&lt;br/&gt;&lt;br/&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-K4MwrsjLM3U/TqcdwOnqKlI/AAAAAAAAAfM/7XhQKRVkQx4/s1600/Intaller.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 209px; height: 155px;" src="http://4.bp.blogspot.com/-K4MwrsjLM3U/TqcdwOnqKlI/AAAAAAAAAfM/7XhQKRVkQx4/s400/Intaller.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5667531370464422482" /&gt;&lt;/a&gt;

&lt;br/&gt;&lt;br/&gt;

W kodzie przekłada się to na coś takiego.

&lt;pre class="brush:csharp"&gt;
...
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
  this.serviceProcessInstaller1,
  this.serviceInstaller1,
  this.serviceInstaller2});
...
&lt;/pre&gt;

Instalację przeprowadzamy standardowo przy pomocy narzędzia &lt;i&gt;InstallUtil&lt;/i&gt;. Zadba ono o to aby zainstalować obie usługi za jednym razem. Następnie, przy debugowaniu najpierw uruchamiamy tą drugą, dodatkową usługę, podczepiamy się do niej przy pomocy opcji &lt;i&gt;Attach to process...&lt;/i&gt;, stawiamy pułapkę w kodzie pierwszej usługi i dopiero ją uruchamiamy. To zadziała ponieważ obie usługi zostaną uruchomione w jednym procesie, a co więcej otrzymujemy to za darmo. Odpowiada za to metoda &lt;i&gt;ServiceIntaller.Install&lt;/i&gt;, której fragment przytaczam poniżej.

&lt;pre class="brush:csharp"&gt;
int serviceType = 0x10;
...
if (numberOfServices &gt; 1)
{
  serviceType = 0x20;
}
...
NativeMethods.CreateService(databaseHandle, this.ServiceName, this.DisplayName, 0xf01ff, serviceType, (int) this.StartType, 1, str3, null, IntPtr.Zero, dependencies, servicesStartName, password);
...
&lt;/pre&gt;

&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682450(v=vs.85).aspx"&gt;CreateService&lt;/a&gt; to natywna metoda WinAPI, która dodaje usługę do bazy danych menadżera usług. Istotny jest jej piąty parametr &lt;i&gt;serviceType&lt;/i&gt;, może przyjąć kilka wartości ale nas interesują dwie:

&lt;ul&gt;

&lt;li&gt;SERVICE_WIN32_OWN_PROCESS = 0x00000010 oznacza, że każda usługa działa w swoim procesie&lt;/li&gt;

&lt;li&gt;SERVICE_WIN32_SHARE_PROCESS = 0x00000020 oznacza, że usługi mogą dzielić jeden proces&lt;/li&gt;
&lt;/ul&gt;

Jeśli liczba usług jest większa niż 1 to &lt;i&gt;ServiceIntaller.Install&lt;/i&gt; używa flagi &lt;i&gt;SERVICE_WIN32_SHARE_PROCESS&lt;/i&gt;, a w przeciwnym wypadku &lt;i&gt;SERVICE_WIN32_OWN_PROCESS&lt;/i&gt;. 

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-8675063622058003776?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/BVYu2twrHCY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/BVYu2twrHCY/wiele-usug-w-jednym-procesie.html</link><author>noreply@blogger.com (Michał Komorowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-Mvxy8h7t-pQ/TqcdoY56tPI/AAAAAAAAAfA/GO5AVryoki4/s72-c/Project.jpg" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/10/wiele-usug-w-jednym-procesie.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-645717811047684406</guid><pubDate>Mon, 24 Oct 2011 13:37:00 +0000</pubDate><atom:updated>2011-10-24T22:20:30.191+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">narzędzia</category><title>PrintScreen</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

Ostatnimi czasy zdarzyło się, że musiałem intensywnie korzystać z przycisku &lt;i&gt;Print Scrn&lt;/i&gt;, tworzyć wiele zrzutów ekranu, a potem jeszcze edytować je w programie graficznym. W pewnym momencie stwierdziłem, że proces ten trzeba jakoś zautomatyzować. Z pomocą przyszedł program &lt;a href="http://www.gadwin.com/download/index.htm#PrintScreen"&gt;PrintScreen&lt;/a&gt;. 

&lt;br/&gt;&lt;br/&gt;

W wersji podstawowej jest bezpłatny. Reaguje na standardowy przycisk &lt;i&gt;Print Scrn&lt;/i&gt; ale można to zmienić. Zrzuty ekranu wypluwa w wybranym formacie, do wskazanego katalogu. Nazwy plików mogą być generowane automatycznie np.: ScreenSchot001, ScreenSchot002 itd. Bardzo spodobało mi się to, że jeśli usuniemy np.: plik ScreenSchoot002 i w ten sposób powstanie luka w numeracji to zostanie ona zapełniona przez następny plik. Program umie również wyświetlić podgląd zrzutu, a przed zapisaniem na dysk umożliwia np.: zmianę wielkości obrazka. W zależności od konfiguracji robi zrzut całego ekranu, wybranego okna lub wskazanego fragmentu.

&lt;br/&gt;&lt;br/&gt;


Nie jest to nic co przyprawia o zawrót głowy ale doskonale spełnia swoją funkcję - po prostu kawał dobrze wykonanej roboty. Program ten zagości na stale w mojej skrzynce narzędziowej i polecam go każdemu komu nie wystarcza standardowa funkcjonalność systemu operacyjnego dotycząca tworzenia zrzutów ekranu.

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-645717811047684406?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/G3oRUWGQ4P4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/G3oRUWGQ4P4/ostatnimi-czasy-zdarzyo-sie-ze-musiaem.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>2</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/10/ostatnimi-czasy-zdarzyo-sie-ze-musiaem.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-6866352350440327027</guid><pubDate>Tue, 13 Sep 2011 20:02:00 +0000</pubDate><atom:updated>2011-09-13T22:05:09.931+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">różne</category><title>Okazja do wzięcia udziału w ciekawych kursach</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

Uniwersytet Standforda organizuje zdalne kursy poświęcone &lt;a href="http://www.ml-class.com/"&gt;uczeniu maszyn&lt;/a&gt; (ang. &lt;i&gt;machine learning&lt;/i&gt;), &lt;a href="http://www.ai-class.com/"&gt;sztucznej inteligencji&lt;/a&gt; oraz &lt;a href="http://www.db-class.org/"&gt;bazom danych&lt;/a&gt;. Zajęcia są bezpłatne i zaczynają się w październiku, a potrwają do grudnia. Kursy składają się nie tylko z wykładów, ale również z rożnych zadań do rozwiązania, będzie można również zadawać pytania. Moim zdaniem to wspaniała okazja, aby zdobyć albo odświeżyć dużo cennej wiedzy. Na każdy z tych wykładów zapisało się już ponad 50 tysięcy osób!

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-6866352350440327027?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/OAoEheT8Gow" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/OAoEheT8Gow/okazja-do-wziecia-udziau-w-ciekawych.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>1</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/09/okazja-do-wziecia-udziau-w-ciekawych.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-1238767145825961638</guid><pubDate>Mon, 12 Sep 2011 19:06:00 +0000</pubDate><atom:updated>2011-09-12T21:12:01.741+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">Visual Studio</category><category domain="http://www.blogger.com/atom/ns#">IntelliTrace</category><title>IntelliTrace - problem ze zdarzeniem</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

Jakiś czas temu pracując z IntelliTrace próbowałem zdefiniować zdarzenie diagnostyczne dla pewnej metody. Dla ustalenia uwagi niech jej sygnatura wygląda tak, jak poniżej.

&lt;br/&gt;&lt;br/&gt;

&lt;i&gt;string Flip(string s)&lt;/i&gt;

&lt;br/&gt;&lt;br/&gt;

Moim celem było, aby opis zdarzenia zawierał wynik zwrócony przez metodę oraz wartość argumentu &lt;i&gt;s&lt;/i&gt;. Inaczej mówiąc, aby w oknie &lt;i&gt;IntelliTrace Events View&lt;/i&gt; w Visual Studio 2010 zdarzenie zarejestowane dla wywołania metody z argumentem &lt;i&gt;s="Hello"&lt;/i&gt; i wynikiem &lt;i&gt;"olleH"&lt;/i&gt; wyglądalo tak:

&lt;br/&gt;&lt;br/&gt;

&lt;i&gt;"olleH" Flip("Hello")&lt;/i&gt;

&lt;br/&gt;&lt;br/&gt;

O definiowaniu zdarzeń IntelliTrace już pisałem (&lt;a href="http://www.michalkomorowski.com/2010/05/wasne-zdarzenia-intellitrace.html"&gt;Własne zdarzenia IntelliTrace!&lt;/a&gt;, &lt;a href="http://www.michalkomorowski.com/2010/06/wasne-zdarzenia-intellitrace-2.html"&gt;Własne zdarzenia IntelliTrace 2&lt;/a&gt;) dlatego nie będę opisywał całego procesu. Przytoczę już gotową definicję zdarzenia:

&lt;pre class="brush: xml"&gt;
&amp;lt;DiagnosticEventSpecification enabled="true"&amp;gt;
  &amp;lt;Bindings&amp;gt;
    &amp;lt;Binding&amp;gt;
      &amp;lt;ModuleSpecificationId&amp;gt;FibTest.exe&amp;lt;/ModuleSpecificationId&amp;gt;
        &amp;lt;TypeName&amp;gt;Utilities&amp;lt;/TypeName&amp;gt;
        &amp;lt;MethodName&amp;gt;Flip&amp;lt;/MethodName&amp;gt;
        &amp;lt;MethodId&amp;gt;Utilities.Flip(System.String):System.String&amp;lt;/MethodId&amp;gt;
        &amp;lt;ShortDescription _locID="shortDescription.Utilities.Flip"&amp;gt;"{0}" Flip("{1}")&amp;lt;/ShortDescription&amp;gt;
        &amp;lt;LongDescription _locID="longDescription.Utilities.Flip"&amp;gt;"{0}" Flip("{1}")&amp;lt;/LongDescription&amp;gt;
        &amp;lt;DataQueries&amp;gt;
          &amp;lt;DataQuery index="-1" maxSize="100" type="String" query="" /&amp;gt;
          &amp;lt;DataQuery index="1" maxSize="100" type="String" query="" /&amp;gt;
        &amp;lt;/DataQueries&amp;gt;
        &amp;lt;ProgrammableDataQuery&amp;gt;
          &amp;lt;ModuleName&amp;gt;&amp;lt;/ModuleName&amp;gt;
          &amp;lt;TypeName&amp;gt;&amp;lt;/TypeName&amp;gt;
        &amp;lt;/ProgrammableDataQuery&amp;gt;
    &amp;lt;/Binding&amp;gt;
  &amp;lt;/Bindings&amp;gt;
  ...
&amp;lt;/DiagnosticEventSpecification&amp;gt;
&lt;/pre&gt;

Niestety ku moje zdziwieniu to nie zadziałało. Zdarzenie zostało zarejestrowane, ale w oknie &lt;i&gt;IntelliTrace Events View&lt;/i&gt; zamiast zobaczyć upragniony wynik otrzymałem komunikat: &lt;i&gt;An error occured while fetching the data for this event&lt;/i&gt;. Zajrzałem, więc do wcześniej zdefiniowanych przez siebie zdarzeń i przypomniałem sobie o jednej rzeczy. Aby odwołać się do wartości zwróconej przez metodę należy ustawić atrybut &lt;i&gt;onReturn&lt;/i&gt;.

&lt;pre class="brush: xml"&gt;
...
&amp;lt;Binding onReturn="true"&amp;gt;
...
&lt;/pre&gt;

Niestety to też nie pomogło. Ponownie zajrzałem więc do wcześniej przygotowanych zdarzeń i na pierwszy rzut oka wszystko wyglądało tak samo. Po chwili zastanowienia doszedłem do wniosku, że przyczyną kłopotów może być to, że próbuję odwołać się zarówno do wartości argumentów jak i do wartości zwracanej przez metodę. Wcześniej czegoś takiego nie próbowałem. Zamiast jednego przygotowałem więc dwa zdarzenia. W jednym odczytuję wartość argumentu przekazanego do metody, a w drugim wynik zwrócony przez metodę.

&lt;pre class="brush: xml"&gt;
...
&amp;lt;Binding onReturn="false"&amp;gt;
  ...
  &amp;lt;ShortDescription _locID="shortDescription.Utilities.Flip"&amp;gt;Flip("{0}")&amp;lt;/ShortDescription&amp;gt;
  &amp;lt;LongDescription _locID="longDescription.Utilities.Flip"&amp;gt;Flip("{0}")&amp;lt;/LongDescription&amp;gt;
  &amp;lt;DataQueries&amp;gt;
    &amp;lt;DataQuery index="1" maxSize="100" type="String" query="" /&amp;gt;
  &amp;lt;/DataQueries&amp;gt;
  ...
&amp;lt;/Binding&amp;gt;
...
&lt;/pre&gt;

&lt;pre class="brush: xml"&gt;
...
&amp;lt;Binding onReturn="true"&amp;gt;
  ...
  &amp;lt;ShortDescription _locID="shortDescription.Utilities.Flip"&amp;gt;Flip returns "{0}"&amp;lt;/ShortDescription&amp;gt;
  &amp;lt;LongDescription _locID="longDescription.Utilities.Flip"&amp;gt;Flip returns "{0}"&amp;lt;/LongDescription&amp;gt;
  &amp;lt;DataQueries&amp;gt;
    &amp;lt;DataQuery index="-1" maxSize="100" type="String" query="" /&amp;gt;
  &amp;lt;/DataQueries&amp;gt;
  ...
&amp;lt;/Binding&amp;gt;
...
&lt;/pre&gt;

To zadziałało, zostały zarejestrowane dwa zdarzenia, jedno z opisem &lt;i&gt;Flip("Hello")&lt;/i&gt;, a drugie z opisem &lt;i&gt;Flip returns "olleh"&lt;/i&gt;. Moim zdaniem to spore ograniczenie IntelliTrace, ale nie ma rady i trzeba o tym po prostu pamiętać.
&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-1238767145825961638?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/nY_Wy1YfolM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/nY_Wy1YfolM/intellitrace-problem-ze-zdarzeniem.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/09/intellitrace-problem-ze-zdarzeniem.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-5896436685847618500</guid><pubDate>Sun, 11 Sep 2011 15:23:00 +0000</pubDate><atom:updated>2011-09-13T13:57:44.675+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Londyn</category><title>Londyn - trochę nietypowa wycieczka</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

Londyn to miasto odwiedzane rokrocznie przez miliony turystów. Twierdza Tower, Tower Bridge, Pałac Buckingham to tylko z niektórych miejsc, które znajdują się na liście do zobaczenia dla wielu odwiedzających. Ja też nie omieszkałem pokazać się w tych i wielu innych miejscach, ale w tym poście chciałbym zachęcić do wizyty w innym, trochę bardziej nietypowym miejscu. Mam na myśli &lt;a href="http://www.thorpepark.com/"&gt;Thorpe Park&lt;/a&gt; czyli wesołe miasteczko zlokalizowane pod Londynem (ok. 40 minut pociągiem + 10 minut autobusem). Bilet kosztuje dla dorosłych 40 funtów, ale cenę można zbić o 35% przy zakupie online lub nawet 50% przy zakupie grupowym (7 biletów).

&lt;br/&gt;&lt;br/&gt;

Miasteczko oferuje bardzo dużo dla miłośników przeciążeń, chyba nawet więcej niż konkurencyjny park &lt;a href="http://www.altontowers.com/"&gt;Alton Towers&lt;/a&gt;. Wspomnę tylko o &lt;a href="http://en.wikipedia.org/wiki/Stealth_(roller_coaster)"&gt;Stealth&lt;/a&gt;, w którym osiągamy prędkość ok. 130 km/h w ciągu 1.8 sekundy, maksymalne przeciążenie to prawie 5G (wciska w fotel), a najwyższy punkt kolejki znajduje się 60m nad ziemią. Robi niesamowite wrażenie, do tego stopnia, że bez zastanowienia zdecydowałem się na drugą przejażdżkę. 

&lt;br/&gt;&lt;br/&gt;

Z rzeczy praktycznych to w parku jest tłoczno nawet poza sezonem. Mówię tutaj o weekendach, w ciągu tygodnia może być lepiej. W związku z tym należy przygotować się na długie czekanie, nawet do 2 godzin aby dostać się na kilkunasto sekundową przejażdżkę! Kolejki można ominąć na dwa sposoby. Pierwszy to tzw. &lt;i&gt;single riders&lt;/i&gt;. Polega to na tym, że najpierw do wagoników ładowane są osoby z normalnej kolejki i jeśli zostają wolne miejsca (bo ktoś nie chce jechać sam tylko z przyjaciółmi) to wsiada osoba z kolejki dla &lt;i&gt;single riders&lt;/i&gt;. Kolejka ta przeważnie jest dużo krótsza niż normalna, ale po pierwsze nie jest dostępna wszędzie, a po drugie dużo zależy od szczęścia. Równie dobrze może być tak, że czas oczekiwania będzie taki jak w normalnej kolejce.

&lt;br/&gt;&lt;br/&gt;

Drugi sposób jest dużo skuteczniejszy, ale nie ma nic za darmo i to dosłownie. Można kupić bilety &lt;i&gt;fast tracks&lt;/i&gt;, które pozwalają wejść na atrakcje bez czekania w kolejce. Pojedynczy bilet (jeden przejazd na jednej atrakcji) to koszt od 2 do 5 funtów. Czy warto? Niech każdy odpowie sobie samemu, czy woli czekać czy nie.

&lt;br/&gt;&lt;br/&gt;

Wizytę w Thorper Park szczerze polecam wszystkim, którzy lubią takie atrakcje, szczególnie, że jest zlokalizowany blisko Londynu. Ja bawiłem się tam naprawdę dobrze.

Linki do poprzednich postów z serii na temat życia w Londynie:

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-poczatek.html"&gt;Początek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-ceny-jedzenia.html"&gt;Ceny jedzenia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-pogotowie.html"&gt;Pogotowie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-przechodzenia-przez-ulice.html"&gt;Przechodzenie przez ulicę&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-kosze-na-smieci.html"&gt;Kosze na śmieci&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/08/londyn-metro-troche-narzekania.html"&gt;Metro (trochę narzekania)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/08/londyn-zamieszki.html"&gt;Zamieszki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/08/londyn-metro-wskazowki.html"&gt;Londyn - metro (wskazówki)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-5896436685847618500?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/-Ni0M33cB-0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/-Ni0M33cB-0/londyn-to-miasto-odwiedzane-rokrocznie.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/09/londyn-to-miasto-odwiedzane-rokrocznie.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-1677791788834083952</guid><pubDate>Sun, 04 Sep 2011 14:19:00 +0000</pubDate><atom:updated>2011-09-04T16:26:40.221+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">Visual Studio</category><category domain="http://www.blogger.com/atom/ns#">IntelliTrace</category><title>IntelliTrace - schemat XSD</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

Swego czasu w postach &lt;a href="http://www.michalkomorowski.com/2010/05/wasne-zdarzenia-intellitrace.html"&gt;Własne zdarzenia IntelliTrace!&lt;/a&gt; oraz &lt;a href="http://www.michalkomorowski.com/2010/06/wasne-zdarzenia-intellitrace-2.html"&gt;Własne zdarzenia IntelliTrace 2&lt;/a&gt; opisałem jak zmodyfikować plik &lt;i&gt;CollectionPlan.xml&lt;/i&gt; zawierający plan działania IntelliTrace (historycznego debuggera) tak, aby zdefiniować swoje własne zdarzenie IntelliTrace (ważny punkt w historii działania programu kiedy IntelliTrace nagrywa stan aplikacji). Ostatnio wróciłem do tego zagadnienia i "bawię się" testując różne możliwości IntelliTrace. Niestety czasami, po zmodyfikowaniu pliku &lt;i&gt;CollectionPlan.xml&lt;/i&gt;, przy próbie uruchomienia debuggera otrzymywałem błąd np.:

&lt;br/&gt;&lt;br/&gt;

&lt;i&gt;
error VSLG4001: The specified collection plan is invalid: 'C:\CollectionPlan.xml'.
More information: The 'type' attribute is invalid - The value 'Object' is invalid according to its datatype 'urn:schemas-microsoft
-com:visualstudio:tracelog:ClrType' - The Enumeration constraint failed.
&lt;/i&gt;

&lt;br/&gt;&lt;br/&gt;

Komunikat jest czytelny, wartość &lt;i&gt;Object&lt;/i&gt; dla atrybutu &lt;i&gt;type&lt;/i&gt; jest niedozwolona. Metodą prób i błędów można wywnioskować, jakie wartości są poprawne, ale to męczące i niewydajne. Pomyślałem więc, że skoro zawartość pliku &lt;i&gt;CollectionPlan.xml&lt;/i&gt; to dokument XML, to musi on być walidowany przy pomocy odpowiedniego schematu XSD. Ale gdzie go szukać? Przejrzałem zawartość katalogu instalacyjnego Visual Studio 2010 i niczego nie znalazłem.

&lt;br/&gt;&lt;br/&gt;

Stwierdziłem więc, że zajrzę do biblioteki &lt;i&gt;Microsoft.VisualStudio.IntelliTrace&lt;/i&gt; (pisałem o niej w poście &lt;a href="http://www.michalkomorowski.com/2010/11/poznaj-swoj-program.html"&gt;Poznaj swój program&lt;/a&gt;), która umożliwia programową analizę logów IntelliTrace, ale nie tylko. Biblioteka ta wykorzystywana jest również przez program IntelliTrace.exe (o tym też pisałem w poście &lt;a href="http://www.michalkomorowski.com/2010/07/uzywanie-intellitrace-poza-visual.html"&gt;Używanie IntelliTrace poza Visual Studio 2010!&lt;/a&gt;), który znajdziemy w katalogu instalacyjnym Visual Studio 2010. Program ten służy do uruchomienia historycznego debuggera i kiedy używamy IntelliTrace z poziomu Visual Studio, to korzystamy właśnie z tego programu. Skoro tak to doszedłem do wniosku, że walidacja konfiguracji i schemat XSD znajdują się właśnie w  tej bibliotece.

&lt;br/&gt;&lt;br/&gt;

Okazało się to strzałem w dziesiątkę. Bibliotekę załadowałem do .NET Reflector'a. Najpierw zlokalizowałem w zasobach komunikat z błędem. Następnie sprawdziłem gdzie jest używany i znalazłem tylko jedno takie miejsce, a stamtąd już szybko doszedłem do wywołania metody &lt;i&gt;public static XmlSchema GenerateXmlSchema()&lt;/i&gt;. Niestety okazało się, że nie mogę jej wywołać z własnego kodu, ponieważ znajduje się w klasie &lt;i&gt;internal class ConfigMessagePacker&lt;/i&gt;. Skopiowałem więc jej kod (ok. 1200 linii) do swojego programu i po chwili miałem już XSD.

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-1677791788834083952?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/-P9_kjIb_Yk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/-P9_kjIb_Yk/intellitrace-schemat-xsd.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/09/intellitrace-schemat-xsd.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-5272461297366494444</guid><pubDate>Wed, 31 Aug 2011 18:05:00 +0000</pubDate><atom:updated>2011-08-31T20:10:25.449+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">COM/COM+</category><title>Krótko o instalowaniu ServicedComponent</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

W dwóch poprzednich artykułach na temat zarządzanych komponentów COM+ pisałem, że instaluje się je przy użyciu narzędzia &lt;i&gt;regsvcs.exe&lt;/i&gt;. Tak oczywiście jest, ale ostatnio ku swojemu zaskoczeniu zauważyłem, że jest to opcjonalne. Jeśli nie zainstalujemy takiego komponentu z poziomu konsoli (np.: &lt;i&gt;regsvcs.exe MyComponent.dll&lt;/i&gt;) to zostanie on zainstalowany automatycznie przy pierwszym wywołaniu jego konstruktora.

&lt;pre class="brush: csharp"&gt;
[assembly: ApplicationName("MyComponent")]
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: System.Reflection.AssemblyKeyFile("MyComponent.snk")]
[assembly: ApplicationAccessControl(false)]
public class MyComponent: ServicedComponent
{
  ...
}

...

//Jeśli komponent nie został wcześniej zainstalowany to zostanie zainstalowany w tym momencie
using (MyComponent cmp = new MyComponent())
{
  ...
}

&lt;/pre&gt;

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-5272461297366494444?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/iumzwhDPwm4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/iumzwhDPwm4/krotko-o-instalowaniu-servicedcomponent.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/08/krotko-o-instalowaniu-servicedcomponent.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-8357435239094329986</guid><pubDate>Thu, 25 Aug 2011 19:17:00 +0000</pubDate><atom:updated>2011-08-31T20:10:32.995+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">COM/COM+</category><title>Jeszcze o ServicedComponent</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

W tym poście wrócę do tematu aplikacji modelu COM+ napisanych w kodzie zarządzanym, który to poruszyłem w poprzednim &lt;a href="http://www.michalkomorowski.com/2011/08/debugowanie-servicedcomponent.html"&gt;artykule&lt;/a&gt;. Tym razem chciałbym zwrócić uwagę na problem wersjonowanie takich komponentów. Upraszczając, chodzi o różnicę pomiędzy katalogiem, z jakiego komponent został zainstalowany w systemie, a katalogiem, w którym znajduje się biblioteka z komponentem jakiej używa dana aplikacja. W szczególności mogą to być inne katalogi np.: &lt;i&gt;c:\Install&lt;/i&gt; oraz &lt;i&gt;c:\bin&lt;/i&gt;.

&lt;br/&gt;&lt;br/&gt;

W takim przypadku łatwo może dość do sytuacji, w której binaria w obu lokalizacjach będą się różnić. Objawy będą różne w zależności od trybu aktywacji (pisałem o nich poprzednio).W przypadku &lt;i&gt;Aplikacji biblioteki&lt;/i&gt; tak długo jak w obu katalogach będą znajdować się biblioteki skompilowane dla tego samego środowiska (32 lub 64 bitowego) nie będzie żadnego problemu (poza bałaganem). Co ciekawe znaczenie ma tylko liczba bitów, wersje bibliotek mogą być inne, różna może być nawet liczba udostępnianych przez komponent metod. Natomiast w przypadku kiedy w jednym katalogu będzie wersja 32 bitowa, a w drugim 64 bitowa przy próbie skorzystania z komponentu dostaniemy wyjątek &lt;i&gt;ComException&lt;/i&gt; o treści &lt;i&gt;Klasa niezarejestrowana...&lt;/i&gt;.

&lt;br/&gt;&lt;br/&gt;

W trybie &lt;i&gt;Aplikacji serwerowej&lt;/i&gt; liczba bitów nie ma znaczenia. Znaczenie ma jednak zawartość bibliotek w obu lokalizacjach. Jeśli będzie różna debugowanie nie będzie możliwe. Jeśli zmieni się interfejs, na przykład do biblioteki zostanie dodana nowa metoda, ale nowa wersja nie zostanie zainstalowana, to przy próbie jej użycia pojawi się wyjątek.

&lt;br/&gt;&lt;br/&gt;

Generalnie problem dotyczy też natywnych komponentów COM+ (piekło COM+) ale z takimi komponentami nie pracowałem dlatego nie znam szczegółów.

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-8357435239094329986?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/Sk1fk887Vw0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/Sk1fk887Vw0/jeszcze-o-servicedcomponent.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/08/jeszcze-o-servicedcomponent.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-3626944189365219148</guid><pubDate>Tue, 23 Aug 2011 21:03:00 +0000</pubDate><atom:updated>2011-08-31T20:10:43.131+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">COM/COM+</category><title>Debugowanie ServicedComponent</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

&lt;a href="http://msdn.microsoft.com/en-us/library/7c05y13x(v=VS.80).aspx"&gt;ServicedComponent&lt;/a&gt; to klasa umożliwiająca tworzenie zarządzanych komponentów/klas, które mogą być użyte w aplikacjach COM+ oraz mogą korzystać z &lt;a href="http://msdn.microsoft.com/en-us/library/k702b5fx(v=VS.80).aspx"&gt;usług COM+&lt;/a&gt;. Jedną z takich usług jest na przykład pula obiektów, czyli coś podobnego do puli połączeń z tą różnicą, że możemy w niej umieścić instancje naszej własnej klasy. 

&lt;br/&gt;&lt;br/&gt;

Aby stworzyć taką specjalną klasę należy wydziedziczyć ją ze wspomnianej klasy &lt;i&gt;ServicedComponent&lt;/i&gt;. Do tej pory nie miałem okazji z niej korzystać, dlatego napotkałem pewne kłopy przy debugowaniu takich zarządzanych komponentów COM+ (dalej będę używał po prostu pojęcia komponent).

&lt;br/&gt;&lt;br/&gt;

Należy zacząć od tego, że są dwa tryby aktywacji komponentów COM+ (zarządzanych lub nie). W pierwszym (tzw. &lt;i&gt;Aplikacja biblioteki&lt;/i&gt;/&lt;i&gt;Library application&lt;/i&gt;) komponent aktywowany jest w procesie aplikacji, która z niego korzysta. W drugim trybie natomiast (tzw. &lt;i&gt;Aplikacja serwera&lt;/i&gt;/&lt;i&gt;Server application&lt;/i&gt;) aktywacja przeprowadzana jest przez dedykowany proces. Tworząc taki komponent możemy określić tryb aktywacji przy pomocy atrybutu &lt;a href="http://msdn.microsoft.com/en-us/library/system.enterpriseservices.applicationactivationattribute.aspx"&gt;ApplicationActivationAttribute&lt;/a&gt;. Tryb ten można również zmienić już po zainstalowaniu komponentu (przy pomocy narzędzia &lt;i&gt;regsvcs.exe&lt;/i&gt;) w konsoli zarządzania w przystawce &lt;i&gt;Usługi składowe&lt;/i&gt; (ang. &lt;i&gt;Component services&lt;/i&gt;). Znajdziemy ją w lokalizacji &lt;i&gt;C:\Windows\System32\comexp.msc&lt;/i&gt;.

&lt;br/&gt;&lt;br/&gt;

Debugowanie takiego zarządzanego komponentu różni się w zależności od trybu aktywacji. Zacznijmy od pierwszego przypadku czyli tzw. &lt;i&gt;Aplikacji biblioteki&lt;/i&gt;. Tutaj sprawa generalnie jest prosta. Skoro komponent aktywowany jest w procesie aplikacji, która z niego korzysta to wystarczy postawić pułapkę w odpowiednim miejscu np.: w kodzie komponentu i tyle. Jest jedno ale. To nie zadziała jeśli aplikacja korzystająca z komponentu została skompilowana na platformę .NET 4.0. Komponent będzie zwracał poprawne wyniki ale jak do tej pory nie udało mi się zmusić VS 2010 do zatrzymania się na pułapce ustawionej w kodzie komponentu albo przejść do tego kodu przy pomocy F11. Jeśli zmienimy platformę na przykład na .NET 3.5 to problem z debugowaniem nie wystąpi.

&lt;br/&gt;&lt;br/&gt;

Trzeba również wiedzieć, że w przypadku tego trybu aktywacji, jeśli mamy zainstalowany komponent 32 bitowy, to proces, który chce z niego skorzystać również musi być 32 bitowy. Analogicznie dla 64 bitów. Informację o błędzie dostaniemy już przy próbie wywołania konstruktora komponentu.

&lt;br/&gt;&lt;br/&gt;

W przypadku trybu "serwerowego" komponent aktywowany jest w innym procesie, więc wersja platformy czy nawet liczba bitów nie mają znaczenia (również przy debugowaniu). Z drugiej strony mamy inny problem ponieważ musimy doczepić się do tego procesu aby go zdebugować czyli skorzystać z funkcji &lt;i&gt;Debug-&gt;Attach to Process...&lt;/i&gt;. Interesujący nas proces nazywa się &lt;i&gt;dllhost.exe&lt;/i&gt;. Kłopot w tym, że na liście może znajdować się kilka procesów o tej nazwie. Pierwsze przybliżenie uzyskamy zawężając listę do tych procesów, które w kolumnie &lt;i&gt;Type&lt;/i&gt; mają wartość &lt;i&gt;Managed...&lt;/i&gt;. W przypadku gdy jest ich kilka można skorzystać z programu &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896653"&gt;Process Explorer&lt;/a&gt; i sprawdzić identyfikator procesu, który korzysta z biblioteki z naszym komponentem.

&lt;br/&gt;&lt;br/&gt;

W jednym z kolejnych postów wrócę jeszcze do tematu i napisze o problemach z wersjonowaniem omawianych komponentów.

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-3626944189365219148?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/ad0c6AftIxo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/ad0c6AftIxo/debugowanie-servicedcomponent.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/08/debugowanie-servicedcomponent.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-5432191984568267198</guid><pubDate>Mon, 22 Aug 2011 20:30:00 +0000</pubDate><atom:updated>2011-08-22T22:32:16.517+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Londyn</category><title>Londyn - metro (wskazówki)</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

W ostatnim poście dotyczącym metra w Londynie obiecałem, że dam kilka wskazówek o tym jak z niego korzystać (o innych środkach transportu nie napiszę bo nie używam). Nie będzie to jakaś wiedza tajemna, ale kiedy jest się po raz pierwszy w Londynie, to nie wszystko jest oczywiste.

&lt;ul&gt;

&lt;li&gt;Nie opłaca się kupować biletów za gotówkę. Tak zakupiony bilet dla pierwszej strefy, w porównaniu do biletu elektronicznego, może być nawet 2 razy droższy. Dla dalszych stref różnica jest mniejsza, ale na przykład większość atrakcji turystycznych znajduje się w pierwszej strefie. &lt;/li&gt;

&lt;li&gt;Osobiście korzystam z karty &lt;i&gt;Oyster&lt;/i&gt; czyli odpowiednika Warszawskiej Karty Miejskiej z tą jednak różnicą, że &lt;i&gt;Oyster&lt;/i&gt; oferuje więcej możliwości. Na taką kartę można załadować bilet okresowy, ale również określoną sumę pieniędzy do wydania na przejazdy tzw. &lt;i&gt;pay as you go&lt;/i&gt;. Z metra korzystam raz na jakiś czas więc jest to dla mnie idealne rozwiązanie.&lt;/li&gt;

&lt;li&gt;Kartę &lt;i&gt;Oyster&lt;/i&gt; kupujemy (ładujemy) w automatach biletowych ustawionych w metrze lub w kasach. Przy zakupie zostanie pobrany zwrotny depozyt wysokosci 5 funtów.&lt;/li&gt;

&lt;li&gt;Nie na każdej stacji znajdziemy kasy biletowe, automaty natomiast tak.&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Ważne!!!&lt;/b&gt;Korzystając z karty &lt;i&gt;Oyster&lt;/i&gt; trzeba koniecznie pamiętać żeby zbliżyć kartę do czytnika (oznaczone sa charakterystycznymi żółtymi kółkami) przy wejściu ale i przy wyjściu z metra. W innym wypadku zostaniemy obciążeni dodatkową opłatą (nie wiem ile dokładnie). W większości wypadków nie ma z tym problemu ponieważ nie przejdziemy przez barierki bez ważnego biletu. Niestety na niektórych stacjach nie ma barierek. Czasami zdarzy się również, że barierki są otwarte ale wtedy też trzeba pamiętać o czytniku.&lt;/li&gt;

&lt;li&gt;Po zarejestrowaniu karty &lt;i&gt;Oyster&lt;/i&gt; na tej &lt;a href="https://oyster.tfl.gov.uk/oyster/link/0004.do"&gt;stronie&lt;/a&gt; będziemy mogli śledzić historię naszych podróży oraz doładować kartę on-line. Jeśli chcemy kupić bilet okresowy na czas dłuższy niż tydzień rejestracja jest wymagana.&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Ważne!!!&lt;/b&gt; Jeśli mamy kartę &lt;i&gt;pay as you go&lt;/i&gt; to mamy zagwarantowane, że danego dnia nie wydamy na przejazdy więcej niż koszt biletu dziennego. Szczegóły można znaleźć &lt;a href="http://www.tfl.gov.uk/tickets/14837.aspx"&gt;tutaj&lt;/a&gt;.&lt;/li&gt;

&lt;li&gt;Warto korzystać ze strony &lt;a href="http://www.tfl.gov.uk"&gt;Transport for London&lt;/a&gt;. Znajdziemy tam bardzo dobrą wyszukiwarkę połączeń oraz informacje o planowanych remontach poszczególnych linii. Generalnie remonty przeprowadzane są w weekendy.&lt;/li&gt;

&lt;li&gt;Nie wszystkie stacje metra mają windę.&lt;/li&gt;

&lt;li&gt;Na stacjach metrach można znaleźć broszurki z planem metra - bardzo przydatne.&lt;/li&gt;

&lt;li&gt;Jeśli ktoś źle znosi wysokie temperaturę lub duchotę, to schodząc do metra (szczególnie korzystając z linii głębinowych) warto zaopatrzyć się w butelkę wody.&lt;/li&gt;

&lt;li&gt;Szczegółowy cennik znajdziemy &lt;a href="http://www.tfl.gov.uk/tickets/14416.aspx"&gt;tutaj&lt;/a&gt;&lt;/li&gt;

&lt;/ul&gt;

Linki do poprzednich postów z serii na temat życia w Londynie:

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-poczatek.html"&gt;Początek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-ceny-jedzenia.html"&gt;Ceny jedzenia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-pogotowie.html"&gt;Pogotowie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-przechodzenia-przez-ulice.html"&gt;Przechodzenie przez ulicę&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-kosze-na-smieci.html"&gt;Kosze na śmieci&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/08/londyn-metro-troche-narzekania.html"&gt;Metro (trochę narzekania)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/08/londyn-zamieszki.html"&gt;Zamieszki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-5432191984568267198?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/oVCTsS4SIns" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/oVCTsS4SIns/londyn-metro-wskazowki.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>3</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/08/londyn-metro-wskazowki.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-2601318988444937916</guid><pubDate>Thu, 18 Aug 2011 20:20:00 +0000</pubDate><atom:updated>2011-08-18T23:34:12.878+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Londyn</category><title>Londyn - zamieszki</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

Z publikacją tego posta czekałem aż zamieszki w Londynie ucichną i sprawa zostanie zapomniana przez media. No i się doczekałem. Obecnie w polskich mediach ciężko znaleźć jakąś wzmiankę na ten temat podczas gdy jeszcze jakiś czas temu można było odnieść wrażenie, że Londyn to strefa wojny.

&lt;br/&gt;&lt;br/&gt;

O zamieszkach usłyszałam po raz pierwszy, kiedy spytała mnie o nie żona. Potem także rodzina i znajomi pytali mnie czy nic mi nie jest, czy jestem bezpieczny itd. Nie dziwię się temu, bo kiedy przeglądam artykuły na temat zamieszek, okraszone strasznymi zdjęciami, to przyznam, że nie wyglądało to fajnie. Osobiście oprócz większej liczby policjantów na ulicach nie widziałem innych skutków rozruchów.

&lt;br/&gt;&lt;br/&gt;

To pokazuje jaka może być różnica pomiędzy rzeczywistością, a obrazem świata przedstawianym przez prasę. Nie twierdzę, że problemu nie było bo problem oczywiście był (jest) i to duży. Wielu ludzi zostało poszkodowanych i przeżyło ciężkie chwile. Ale tak nie było w całym mieście. W tym samym czasie, wbrew temu co pokazywały media, w Londynie toczyło się normalne życie.

&lt;br/&gt;&lt;br/&gt;

Linki do poprzednich postów z serii na temat życia w Londynie:

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-poczatek.html"&gt;Początek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-ceny-jedzenia.html"&gt;Ceny jedzenia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-pogotowie.html"&gt;Pogotowie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-przechodzenia-przez-ulice.html"&gt;Przechodzenie przez ulicę&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-kosze-na-smieci.html"&gt;Kosze na śmieci&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/08/londyn-metro-troche-narzekania.html"&gt;Londyn - metro (trochę narzekania)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-2601318988444937916?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/b3Ib9d6iAts" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/b3Ib9d6iAts/londyn-zamieszki.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>4</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/08/londyn-zamieszki.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-4036880343710006914</guid><pubDate>Sun, 07 Aug 2011 19:02:00 +0000</pubDate><atom:updated>2011-08-07T21:04:51.759+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><title>Kłopoty z Client Profile</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

&lt;i&gt;The type or namespace name 'SomeType' does not exist in the namespace 'SomeNamespace' (are you missing an assembly reference?)&lt;/i&gt; 

&lt;br/&gt;&lt;br/&gt;

Sądzę, że każdy programista .NET spotkał się z powyższym błędem kompilacji. Nie jest to nic wyjątkowego i rozwiązanie problemu jest bardzo łatwe, wystarczy dodać do projektu referencję do brakującej biblioteki. Czy oby na pewno? 

&lt;br/&gt;&lt;br/&gt;

Kilka dni temu napotkałem powyższym błąd kompilatora i rozwiązanie problemu zajęło mi sporo więcej czasu niż normalne kilkanaście sekund. Na początku zdziwiłem się ponieważ niekompilujący się projekt aplikacji zawierał potrzebną referencję, kilka minut wcześniej sam ją dodałem. Na wszelki wypadek podpiąłem ją jednak jeszcze raz i przekompilowałem wszystkie potrzebne projekty ale nic to nie dało. Restart Visual Studio również nie pomógł. Kilka kolejnych prób kompilacji również spełzło na niczym.

&lt;br/&gt;&lt;br/&gt;

Trochę zrezygnowany zabrałem się do przeglądania ustawień felernego projektu i zwróciłem uwagę na to, że korzysta on &lt;a href="http://msdn.microsoft.com/en-us/library/cc656912.aspx"&gt;.NET Framework 4 Client Profile&lt;/a&gt;. Wcześniej nie miałem z tym problemu ale przypomniałem sobie, że w projektach tego typu nie można korzystać z bibliotek, których nie ma w &lt;i&gt;NET Framework 4 Client Profile&lt;/i&gt;. Na próbę zmieniłem opcję &lt;i&gt;Target framework&lt;/i&gt; na &lt;i&gt;.NET Framework 4&lt;/i&gt; i okazało się to strzałem w dziesiątkę. 

&lt;br/&gt;&lt;br/&gt;

W ramach testu zacząłem zmieniać różnym projektom opcję &lt;i&gt;Target framework&lt;/i&gt; na &lt;i&gt;.NET Framework 4 Client Profile&lt;/i&gt; i sprawdzać czy się kompilują. Okazało się, że prawie wszystkie skompilowały się bez żadnego problemu. Dalsze eksperymenty doprowadziły mnie do następującego wniosku:

&lt;br/&gt;&lt;br/&gt;

Błąd zostanie zgłoszony jeśli w projekcie korzystającym z &lt;i&gt;NET Framework 4 Client Profile&lt;/i&gt; &lt;b&gt;użyjemy&lt;/b&gt; biblioteki, która &lt;b&gt;bezpośrednio&lt;/b&gt; lub &lt;b&gt;pośrednio&lt;/b&gt; korzysta z czegoś co nie znajduje się w &lt;i&gt;NET Framework 4 Client Profile&lt;/i&gt;.

&lt;br/&gt;&lt;br/&gt;

Przez &lt;b&gt;użyjemy&lt;/b&gt; rozumiem np.: stworzenie instancji klasy. Samo dodanie referencji do biblioteki czy nawet zaimportowanie przestrzeni nazw przy pomocy &lt;i&gt;using&lt;/i&gt; nie spowoduje błędu. Ważne jest również to, że biblioteka powodująca błąd może znajdować się gdzieś daleko w łańcuchu referencji, co jeszcze utrudnia sprawę. Należy również wiedzieć, że o przynależności lub nie do &lt;i&gt;NET Framework 4 Client Profile&lt;/i&gt; nie decydują opcje kompilacji ale to
z czego korzystamy w danej bibliotece. Listę "zabronionych" rzeczy można znaleźć &lt;a href="http://msdn.microsoft.com/en-us/library/cc656912.aspx"&gt;tutaj&lt;/a&gt;. W moim przypadku błąd powodowała "zabroniona" biblioteka &lt;i&gt;System.Data.OracleClient&lt;/i&gt;, z której korzysta &lt;i&gt;Microsoft.Practices.EnterpriseLibrary.Data.dll&lt;/i&gt;, którą z kolei używam ja.

&lt;br/&gt;&lt;br/&gt;

Sądzę, że warto o tym pamiętać aby zaoszczędzić sobie nerwów szczególnie, że kiedy dodajemy nowy projekt aplikacji (WPF, WinForms, konsola) to domyślnie będzie on korzystał &lt;i&gt;.NET Framework 4 Client Profile&lt;/i&gt;. W większości przypadków jest to dla nas przezroczyste ale zawsze może trafić się ten jeden raz.

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-4036880343710006914?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/-KFGxP5X5CY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/-KFGxP5X5CY/kopoty-z-client-profile.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>2</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/08/kopoty-z-client-profile.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-7059055249802460015</guid><pubDate>Mon, 01 Aug 2011 14:26:00 +0000</pubDate><atom:updated>2011-08-01T22:33:49.732+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Londyn</category><title>Londyn - metro (trochę narzekania)</title><description>&lt;br/&gt;
&lt;div align="justify"&gt;

Dzisiaj napiszę o metrze londyńskim, które należy do najstarszych i najbardziej rozbudowanych na świecie, a z którego w porównaniu do innych środków transportu korzystam najczęściej. Dwanaście linii wijących się pod miastem w porównaniu do jednej budowanej 25 lat w Warszawie robi wrażenie i budzi zazdrość. Ja chciałbym jednak pokazać, że jeśli choć na chwilę zapomnimy o liczbie linii to metro warszawskie zacznie wygrywać z londyńskim pod wieloma względami.

&lt;br/&gt;&lt;br/&gt;

Zacznę od tego, że w londyńskim metrze jest bardzo duszno i gorąco. Nawet jeśli na dworze jest zimno i założyliśmy kurtkę to po zejściu do metra z pewnością ją zdejmiemy. Na przewarzającej liczbie stacji i w pociągach niestety brakuje klimatyzacji. Czytałem, że w najbliższym czasie na jednej z linii mają zostać wprowadzone pociągi z klimatyzacją ale to kropla w morzu potrzeb. Póki co przemieszczanie się metrem to przyjemnych nie należy, a zarząd metra zaleca aby w podróż wybrać się z butelką wody.

&lt;br/&gt;&lt;br/&gt;

Komfortu nie poprawia fakt, że stacje w londyńskim metrze są bardzo małe, szczególnie te głębinowe. Jest akurat tyle miejsca aby zmieścił się pociąg i niewiele więcej. Biorąc pod uwagę to co widziałem, tak na oko przeciętna szerokość peronu to 3-4 metry. Pod tym względem Warszawa bije Londyn na głowę. Mniejsze są również wagony (z ciekawostek to na poszczególnych liniach mają różne rozmiary). W Warszawie bez problemu stoję wyprostowany, w Londynie mieszczę się po środku wagonu.

&lt;br/&gt;&lt;br/&gt;

W londyńskim metrze brakuje również tzw. komór rozprężających powietrze. Powoduje to, że pociąg wjeżdżający na stację wpycha przed sobą ogromną masę powietrza, która uderza w pasażerów. Może to i drobiazg ale pokazuje, że metro w Warszawie należy do nowoczesnych. Potwierdza to, również fakt, że wszystkie stacje metra w Warszawie przystosowane są dla niepełnosprawnych (mam na myśli windy), a w Londynie nie.

&lt;br/&gt;&lt;br/&gt;

Z innych rzeczy to jadąc metrem w Londynie mam wrażenie, że tory do najprostszych nie należą. Obserwując wagon jadący przed nami albo za nami można zauważyć jak nim rzuca, czasami jest jakby trochę wyżej, a czasami niżej :). Metro w Londynie jest również po prostu drugie, nawet biorąc pod uwagę wyższe zarobki. Koszt jednego przejazdy w ramach pierwsze strefy to na tą chwilę 1.9 funta szterlinga i to przy założeniu, że korzystamy z karty magnetycznej (tzw. Oyster). Tradycyjne bilety są jeszcze droższe.

&lt;br/&gt;&lt;br/&gt;

Tyle narzekania. Ideałem byłoby metro nowoczesne jak w Warszawie ale z taką liczbą linii jak w Londynie (może moje wnuki tego doczekają). W kolejnych postach chciałbym dać kilka wskazówek jak korzystać z metra w Londynie.

&lt;br/&gt;&lt;br/&gt;

Linki do poprzednich postów z serii na temat życia w Londynie:

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-poczatek.html"&gt;Początek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-ceny-jedzenia.html"&gt;Ceny jedzenia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-pogotowie.html"&gt;Pogotowie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-przechodzenia-przez-ulice.html"&gt;Przechodzenie przez ulicę&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-kosze-na-smieci.html"&gt;Kosze na śmieci&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-7059055249802460015?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/kDIHt4fyZ-o" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/kDIHt4fyZ-o/londyn-metro-troche-narzekania.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/08/londyn-metro-troche-narzekania.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-386907802252574705</guid><pubDate>Fri, 29 Jul 2011 21:30:00 +0000</pubDate><atom:updated>2011-07-29T23:33:19.950+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Londyn</category><title>Londyn - kosze na śmieci</title><description>&lt;br/&gt;

&lt;div align="justify"&gt;

Z ciekawostek. W Londynie jest bardzo mało koszy. W gruncie rzeczy jeśli mamy do wyrzucenia jakiś papierek, niedopałek papierosa itp. do mamy dwa wyjścia: schować do kieszeni lub wyrzucić na ulicę. Wiele osób, a w szczególności palacze wybierają drugą  opcję. Służby sprzątające są jednak bardzo sprawne dlatego miasto nie jest zaśmiecone. 

&lt;br/&gt;&lt;br/&gt;

Ciekawe jest natomiast dlaczego tych koszy jest tak mało. Kolega stwierdził, że to pozostałość po czasach kiedy aktywna była Irlandzka Armia Republikańska. Kosz na śmieci to doskonałe miejsce na podłożenie bomby i dlatego usunięto je z ulic tylko, że potem "zapomniano" je przywrócić.

&lt;br/&gt;&lt;br/&gt;

Linki do poprzednich postów z serii na temat życia w Londynie:

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-poczatek.html"&gt;Początek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-ceny-jedzenia.html"&gt;Ceny jedzenia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-pogotowie.html"&gt;Pogotowie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-przechodzenia-przez-ulice.html"&gt;Przechodzenie przez ulicę&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/div&gt;

&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-386907802252574705?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/Itdgs04-5vI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/Itdgs04-5vI/londyn-kosze-na-smieci.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/07/londyn-kosze-na-smieci.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-181606829933356774</guid><pubDate>Wed, 27 Jul 2011 18:57:00 +0000</pubDate><atom:updated>2011-07-28T00:42:11.059+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">narzędzia</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">Visual Studio</category><category domain="http://www.blogger.com/atom/ns#">IntelliTrace</category><title>IntelliTrace - Reaktywacja</title><description>&lt;br/&gt;

&lt;div align="justify"&gt; 

Już kawał czasu temu w artykule &lt;a href="http://www.michalkomorowski.com/2010/07/uzywanie-intellitrace-poza-visual.html"&gt;Używanie IntelliTrace poza Visual Studio 2010!&lt;/a&gt; opisałem w jaki sposób uruchomić narzędzie IntelliTrace poza środowiskiem Visual Studio 2010. Przedstawiona przeze mnie metoda miała jednak wadę. Log z nagranym przebiegiem wykonania programu zawierał "tylko" informację o wywołaniach metod czyli drzewo wywołań, a brakowało w nim informacji o zdarzeniach diagnostycznych czyli ważnych punkty w historii wykonania programu np.: wykonanie zapytania do bazy danych.

&lt;br/&gt;&lt;br/&gt;

Ostatnio udało mi się znaleźć ostatni element układanki. Otóż aby log IntelliTrace zawierał wszystkie niezbędne informacje wystarczy wykonać, oprócz opisanych już przeze mnie rzeczy, jeszcze jeden krok czyli zmodyfikować plik &lt;i&gt;CollectionPlan.xml&lt;/i&gt; z planem działania/konfiguracją narzędzia. Znajdujemy w nim linię:

&lt;pre class="brush: xml"&gt;
...
&amp;lt;DiagnosticEventInstrumentation enabled="false"&amp;gt;
...
&lt;/pre&gt;


i zamieniamy na:

&lt;pre class="brush: xml"&gt;
...
&amp;lt;DiagnosticEventInstrumentation enabled="true"&amp;gt;
...
&lt;/pre&gt;

&lt;/div&gt;

&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-181606829933356774?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/1hYsDGM2vTg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/1hYsDGM2vTg/m.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/07/m.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-8292098671538902042</guid><pubDate>Fri, 22 Jul 2011 17:38:00 +0000</pubDate><atom:updated>2011-07-22T19:45:21.608+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Londyn</category><title>Londyn - przechodzenia przez ulicę</title><description>&lt;br/&gt;

&lt;div align="justify"&gt;

W Polsce od maleńkiego uczono mnie, że przez ulicę należy przechodzić na pasach i kiedy pali się zielone światło. Swego czego przekonałem się również ile wynosi mandat za przechodzenie na czerwonym świetle:) Kiedy wyjeżdżam za granicę z założenia stosuję te same zasady, choćby dlatego, żeby nie płacić potencjalnie wyższych mandatów niż w Polsce.

&lt;br/&gt;&lt;br/&gt;

W Londynie (nie wiem czy jest tak w całym Zjednoczonym Królestwie), co mnie bardzo zaskoczyło, sprawa ma się zupełnie inaczej. Zdecydowana większość osób przechodzi na czerwonym świetle i jest to właściwie zasadą. Początkowo miałem jednak pewne skrupuły. O tym, że jest to "dozwolone" przekonałem sie kiedy zobaczyłem, że policja nie reaguje na ten niecny proceder nawet jeśli przechodzi się na czerwonym świetle tuż koło właśnie ruszającego radiowozu! 

&lt;br/&gt;&lt;br/&gt;

Z czego wynika to przyzwolenie na łamanie prawa? Od kolegi dowiedziałem się, że wbrew pozorom wszystko dzieje się w majestacie prawa. Z ciekawości poszukałem informacji na ten temat i wygląda na to, że kolega miał rację. Otóż przepisy dotyczące przechodzenia przez jezdnię sformułowano przy użyciu wyrażeń "should/should not" albo "do/do not" (rada/zalecenie), a nie "must/must not" (zakaz/nakraz). Innymi słowy napisano, że "nie powinno" się przechodzić na czerwonym świetle zamiast, że "jest zabronione/nie wolno" przechodzić na czerwonym świetle.

&lt;br/&gt;&lt;br/&gt;

Takie podejście do przechodzenia przez ulicę z pewnością przyspiesza poruszanie się po Londynie. Trzeba jednak pamiętać, że robimy to na swoją odpowiedzialność. Jeśli zostaniemy potrąceni przez samochód to będzie to nasza wina.

&lt;br/&gt;&lt;br/&gt;

Linki do poprzednich postów z serii na temat życia w Londynie:

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-poczatek.html"&gt;Początek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-ceny-jedzenia.html"&gt;Ceny jedzenia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-pogotowie.html"&gt;Pogotowie&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;

&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-8292098671538902042?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/JXcU4MhyMFQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/JXcU4MhyMFQ/londyn-przechodzenia-przez-ulice.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>3</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/07/londyn-przechodzenia-przez-ulice.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-2489697206093798354</guid><pubDate>Tue, 19 Jul 2011 19:06:00 +0000</pubDate><atom:updated>2011-07-19T21:35:40.905+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">różne</category><category domain="http://www.blogger.com/atom/ns#">narzędzia</category><category domain="http://www.blogger.com/atom/ns#">kariera zawodowa</category><title>See[Mike]Code</title><description>&lt;br/&gt;

&lt;div align="justify"&gt; 

Dzisiaj rozmawiając z kolegami zeszliśmy na temat rekrutacji programistów. Między innymi rozmawialiśmy o narzędziach wspomagających ten proces takich jak &lt;a href="http://codility.com/"&gt;Codility&lt;/a&gt;. Rozmowa ta przypomniała mi, że swego czasu natknąłem się ba bardzo proste ale pomysłowe narzędzie pozwalające na żywo, zdalnie sprawdzić jak potencjalny kandydat radzi sobie z programowaniem. Miałem trudności z przypomnieniem sobie adresu strony dlatego ku pamięci publikuję ten post. Przy okazji sądzę, że narzędzie to może przydać się innym. Mianowicie chodzi o &lt;a href="http://i.seemikecode.com/"&gt;See[Mike]Code&lt;/a&gt;.

&lt;br/&gt;&lt;br/&gt;

Zasada działania jest bardzo prosta. Wchodzimy na stronę &lt;i&gt;See[Mike]Code&lt;/i&gt;, klikamy przycisk &lt;i&gt;New Interview Site&lt;/i&gt; i otrzymujemy dwa adresy. Jeden wysyłamy do kandydata, a drugi zachowujemy dla siebie. O wyznaczonej porze prosimy aby kandydat uruchomił przeglądarkę i wszedł na podany adres. Jego oczom ukarze się taki widok:

&lt;br/&gt;&lt;br/&gt;

&lt;a href="http://3.bp.blogspot.com/-ADV57NCdDwg/TiXV0R-uxCI/AAAAAAAAAa0/eEmZo0fUThE/s1600/Candidate.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 305px;" src="http://3.bp.blogspot.com/-ADV57NCdDwg/TiXV0R-uxCI/AAAAAAAAAa0/eEmZo0fUThE/s400/Candidate.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5631142003253101602" /&gt;&lt;/a&gt;

&lt;br/&gt;&lt;br/&gt;

Kiedy wejdziemy pod drugi adres wyświetlona zostanie dość podobna strona. Teraz prosimy kandydata aby wykonał jakieś proste zadanie programistyczne np.: słynne &lt;a href="http://devpytania.pl/questions/126/jak-napisac-fizzbuzz-w-twoim-ulubionym-jezyku-programowania"&gt;FizzBuzz&lt;/a&gt;, a jego poczynania możemy obserwować na ekranie naszego komputera. &lt;i&gt;See[Mike]Code&lt;/i&gt; nie udostępnia takich dobrodziejstw jak IntelliSense ale w przypadku prostych zadań, takich jak wspomniane FizzBuzz, nie jest to konieczne.

&lt;br/&gt;&lt;br/&gt;

Jestem przekonany, że na polskim rynku nie mamy sytuacji, w której jak to napisał Jeff Atwood na swoim &lt;a href="http://www.codinghorror.com/blog/2007/02/why-cant-programmers-program.html"&gt;blogu&lt;/a&gt;:

&lt;br/&gt;&lt;br/&gt;

&lt;i&gt;Like me, the author is having trouble with the fact that 199 out of 200 applicants for every programming job can't write code at all. I repeat: they can't write any code whatsoever.&lt;/i&gt;

&lt;br/&gt;&lt;br/&gt;

Sądzę jednak, że dobrze mieć w swoim repertuarze takie narzędzie.
&lt;/div&gt;

&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-2489697206093798354?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/NGdu0hnwXm4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/NGdu0hnwXm4/seemikecode.html</link><author>noreply@blogger.com (Michał Komorowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-ADV57NCdDwg/TiXV0R-uxCI/AAAAAAAAAa0/eEmZo0fUThE/s72-c/Candidate.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/07/seemikecode.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364616448054212690.post-745795954002215923</guid><pubDate>Wed, 13 Jul 2011 19:06:00 +0000</pubDate><atom:updated>2011-07-22T19:45:55.973+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Londyn</category><title>Londyn - pogotowie</title><description>&lt;br/&gt;

&lt;div align="justify"&gt; 

Dzisiaj idąc do pracy byłem świadkiem jak pogotowie udzielało pomocy kobiecie, która zasłabła na moście London Bridge. Co w tym takiego ciekawego, ze postanowiłem o tym napisać? Moją uwagę zwrócił środek transportu jakim przyjechał ratownik czyli rower. Słyszałem o tym ale po raz pierwszy widziałem. 

&lt;br/&gt;&lt;br/&gt;

Temat podrążyłem trochę bardziej i dowiedziałem się, że w Londynie pogotowie posługuje się oczywiście samochodami ale również motocyklami (&lt;i&gt;motorcycle responders&lt;/i&gt;) i rowerami (&lt;i&gt;cycle responders&lt;/i&gt;). Dwa ostatnie środki transportu używane są w najbardziej ruchliwych/zakorkowanych dzielnicach tak aby nawet w godzinach szczytu dotrzeć do poszkodowanego w jak najkrótszym czasie. Za takim rowerowym pogotowiem wysyłany jest również ambulans. Jeśli jednak okaże się, ze poszkodowany nie musi zostać przetransportowany do szpitala to ratownik może odwołać wyjazd. Dzięki takiemu podejściu, od momentu wprowadzenia pogotowania rowerowego (10 lat temu) ambulanse musiały wyjechać o 20 tysięcy razy mniej, co przekłada się przecież na konkretne pieniądze. Inny niespotykany w Polsce "wynalazek" to Ambulance community responder czyli jednoosobowe pogotowie samochodowe, w którym pracują ochotnicy. Ich celem jest dotarcie do pacjenta i utrzymanie go przy życiu, aż do przybycia ambulansu, których liczba jest ograniczona. 

&lt;br/&gt;&lt;br/&gt;

O Brytyjskiej służbie zdrowia słyszałem dwie opinie, ze jest zła albo, że jest bardzo zła. Mam nadzieję, ze nie będę miał okazji tego zweryfikować ale przynajmniej pogotowie wygląda tutaj na dobrze zorganizowane i sprawnie działające. 

&lt;br/&gt;&lt;br/&gt;

Linki do poprzednich postów z serii na temat życia w Londynie:

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-poczatek.html"&gt;Początek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.michalkomorowski.com/2011/07/londyn-ceny-jedzenia.html"&gt;Ceny jedzenia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;

&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/364616448054212690-745795954002215923?l=www.michalkomorowski.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BlogMichalaKomorowskiego/~4/byTObJHaGyg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/BlogMichalaKomorowskiego/~3/byTObJHaGyg/londyn-pogotowie.html</link><author>noreply@blogger.com (Michał Komorowski)</author><thr:total>0</thr:total><feedburner:origLink>http://www.michalkomorowski.com/2011/07/londyn-pogotowie.html</feedburner:origLink></item></channel></rss>

