czwartek, 29 maja 2014

Task Scheduler - Windows Server 2000 vs 2008R2

Przenosząc skrypty .bat pomiędzy serwerami z serwera Windows 2000 na Windows 2008r2 napotkałem pewne problemy. Dlaczego warto robić skrypty .bat można się dowiedzieć choćby z książki A.Hunt, D.Thomas Pragmatyczny programista. Od czeladnika do mistrza w rozdziale "Wszechobecna automatyzacja".

Przenosząc te skrypty, miałem okazję spotkać się z dwoma niemiłymi dla mnie niespodziankami. 
Po pierwsze, zmienił się format daty, jaki stosuje się w skryptach. Aby uzyskać format daty yyyy-MM-ss (rok-miesiąc-dzień) w starszym windowsie (win xp, win server 2000) wystarczyło podać:
echo %DATE:~0,4%-%DATE:~5,2%-%DATE:~8,2%

W windows 7 oraz server 2008r2 trzeba to zrobić nieco inaczej:
@echo off
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
@echo on
echo  %mydate%


UWAGA: echo to... taki Console.Writeline w bashu... czyli... komenda na wypisanie zmiennej na ekran konsoli.


Drugim problemem z jakim się napotkałem to... uruchomienie programu w task schedulerze. Aby nie było zbyt łatwo, w ustawieniach (settings) task schedulera nie można podać pełnej ścieżki skryptu/programu tylko trzeba... wykorzystać 2 osobne, przeznaczone do tego pola (osobne pole na nazwę skryptu, osobne na nazwę programu):




P.S. Z innych spraw, jakie wynikły przy okazji przenoszenia tych skryptów na inny serwer, to ustawianie uprawnień do baz danych, linked serwerów i innych kwestii bezpieczeństwa, ale... to by trzeba było ustawić niezależnie typów serwerów (źródłowych/docelowych).
















sobota, 24 maja 2014

KeePass – przechowuj hasła bezpiecznie

Jednym z problemów, z jakimi spotykają się różni użytkownicy komputerów, posiadający dostęp do wielu zasobów (np. aplikacji internetowych, baz danych itp.) jest problem związany z ilością potrzebnych loginów i haseł. W teorii hasło do każdego konta powinno być inne, jednak w praktyce bardzo trudno jest pamiętać 20-50 różnych haseł do różnych kont. Na szczęście, z pomocą przychodzi nam darmowa aplikacja "KeePass", która będzie przechowywała za nas odpowiednie loginy i hasła w sposób bezpieczny (zaszyfrowany). My, jako użytkownicy, jedynie potrzebujemy znać hasło do naszego pliku z zaszyfrowanymi danymi w KeePass (który możemy przenosić między komputerami, np. za pośrednictwem pendrive), a już szczegółowe loginy i hasła do konkretnych stron, aplikacji, usług, baz danych znajdować się będą w KeePass-ie. 

Linki: 

środa, 14 maja 2014

Korzystanie z kilku plików konfiguracyjnych (*.config)

Jak powszechnie wiadomo, w jednej solucji możemy mieć wiele projektów. Każdy z tych projektów może posiadać własny plik konfiguracyjny. Problem może się pojawić w sytuacji, gdy w jednej solucji chcemy korzystać z wielu plików konfiguracyjnych. Przyjrzyjmy się pewnemu realnemu scenariuszowi.

Mamy nasza przykładową aplikację konsolową, która poprawnie działa. Zaszła jednak potrzeba wykorzystania web serwisu (WCF). Zgodnie z dobrymi praktykami, do obsługi WCF tworzymy nowy, osobny projekt jako bibliotekę DLL ('class library'). Aplikacja konsolowa, posiadała już swój plik konfiguracyjny (App.config), więc próba odwołania się konfiguracji naszej biblioteki za pomocą obiektu "ConfigurationManager" spowodowała przeglądanie pliku konfiguracyjnego aplikacji. Ponieważ chcemy oddzielić konfigurację biblioteki od konfiguracji aplikacji potrzebujemy mieć oba pliki rozdzielone oraz możliwość czytania z obu plików.

Jak to należy zrobić?
Rozwiązanie można podzielić na dwa etapy. Konfiguracyjny oraz programistyczny:

W projekcie:
a) zmieniamy nazwę pliku konfiguracyjnego biblioteki, aby oba pliki konfiguracyjne miały różne nazwy
b) we właściwościach pliku konfiguracyjnego biblioteki ustawiamy właściwość "Copy to output Directory" na "Copy always"
c) w projekcie z aplikacją ustawiamy referencję na projekt z biblioteką

W kodzie biblioteki, będziemy się odwoływać do nowego pliku konfiguracyjnego w "niestandardowy" sposób. Pisząc "niestandardowy" mam na myśli w sposób inny niż za pomocą obiektu "ConfigurationManager".

W kodzie, wykorzystujemy obiekt Configuration (System.ServiceModel.Configuration) poprzez wykorzystanie jego właściwości. Przykładowa klasa, za pomocą której będziemy korzystali z nowego pliku konfiguracyjnego wygląda tak:

    public class ConfigurationManagerWrapper
    {
        private Configuration cfg;
        public ConfigurationManagerWrapper()
        {
            var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            var fileMap = new ExeConfigurationFileMap
            {
                ExeConfigFilename = string.Concat(path, "\\mail.config")
            };
            cfg = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
        }
        public string GetSetting(string key)
        {
            AppSettingsSection section = (cfg.GetSection("appSettings") as AppSettingsSection);
            var value = section.Settings[key].Value;
            return value;
        }
        public ChannelEndpointElement GetClient(string key)
        {
            var serviceModel = ServiceModelSectionGroup.GetSectionGroup(cfg);
            var endpoints = serviceModel.Client.Endpoints;
            if (endpoints.Count > 0)
                return endpoints[0];
            return null;
        }
        public T GetSection<T>(string sectionName)
        {
            return (T)ConfigurationManager.GetSection(sectionName);
        }
    }
Bardziej zaawansowany przykład wykorzystania takiego pliku .config można zobaczyć w przeznaczonym do tego projekcie na github mojego autorstwa stworzonym w celu demonstracji kodu.

Pomocne linki:
stackoverflow.com - how-do-i-retrieve-appsettings-from-the-assembly-config-file
weblogs.asp.net - cibrax - getting-wcf-bindings-and-behaviors-from-any-config-source.aspx