17/04/2011

Błąd przy dodawaniu przystawki do konsoli zarządzania

Home

Przystawka certyfikatów (ang. Certificates Snap-in) pozwala na przeglądanie magazynu certyfikatów dla użytkownika, usługi czy też komputera. Aby uruchomić to narzędzie wystarczy w wierszu poleceń lub do okienka Uruchom wpisać polecenie certmgr.msc. Problem polega na tym, że tak uruchomiona przystawka certyfikatów pokaże nam tylko magazyn dla bieżącego użytkownika.

Jeśli chcemy zobaczyć magazyn certyfikatów komputera, tak było w moim przypadku, czeka nas trochę więcej pracy. Zaczynamy od uruchomienia konsoli zarządzania (ang. Microsoft Management Console) wpisując w wierszu poleceń lub do okienka Uruchom komendę mmc.exe. Następnie wybieramy Plik -> Dodaj/Usuń przystawkę. Przystawka certyfikatów znajduje się na początku listy i po jej wybraniu zostaniemy poproszeni o zaznaczenie jakimi certyfikatami chcemy zarządzać: użytkownika, usługi czy komputera. Na koniec klikamy Ok.

Tak to wygląda w teorii, w praktyce po naciśnięciu przycisku Ok konsola zarządzania raportowała błąd (pokazany poniżej) i kończyła pracę, bez względu na to jaka przystawkę wybrałem.
  Nazwa zdarzenia problemu: APPCRASH
  Nazwa aplikacji: mmc.exe
  Wersja aplikacji: 6.0.6002.18005
  Sygnatura czasowa aplikacji: 49e02760
  Nazwa modułu z błędem: StackHash_7ae8
  Wersja modułu z błędem: 6.0.6002.18327
  Sygnatura czasowa modułu z błędem: 4cb74dd3
  Kod wyjątku: c0000374
  Przesunięcie wyjątku: 00000000000aca57
  Wersja systemu operacyjnego: 6.0.6002.2.2.0.256.6
  Identyfikator ustawień regionalnych: 1045
  Dodatkowe informacje 1: 7ae8
  Dodatkowe informacje 2: fab1f7793b8a08e05290bb8ef1ca5c9e
  Dodatkowe informacje 3: 1607
  Dodatkowe informacje 4: 3b4ea5c6cc4724ebe1b8e0ae80fae1cf
Pan Google nie był zbyt pomocny. Radził aby zainstalować SP2 dla Visty, który już mam zainstalowany. Na innej stronie ktoś twierdził, że problem pojawia się jeśli na jednej maszynie zainstalowane są dwie wersje MSSQL i że trzeba jedną z nich odinstalować. Ja mam akurat zainstalowane dwie wersje MSSQL ale nie miałem najmniejszej ochoty usuwać z dysku żadnej z nich. Trzecia osoba radziła aby na komputerze o zbliżonej do problematycznego konfiguracji, na którym mmc.exe działa, wyeksportować klucze rejestru dotyczące konsoli i zaimportować je na komputerze, na którym występuje problem. Ta rada też nie przypadła mi do gustu ponieważ nie miałem takiego komputera pod ręką. Nie wiedziałem także, na ile ta konfiguracja powinna być "zbliżona" aby było dobrze.

Postanowiłem jednak pójść tropem zawartości rejestru i konfliktu pomiędzy różnymi wersjami MSSQL. Na początek zauważyłem, że na liście dostępnych przystawek znajdują się dwie przystawki o takiej samej nazwie SQL Server Configuration Manager. Zapewne dedykowane dla różnych wersji MSSQL. Następnie postanowiłem zajrzeć do rejestru do klucza, który przechowuje listę wszystkich dostępnych przystawek:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MMC\SnapIns\

Jest ich tam kilkadziesiąt i mają niewiele mówiące nazwy np.: d52e5f54-75d9-4a93-91b7-2215ea5cbed2 ale szybko udało mi się znaleźć klucze odpowiadające przystawce SQL Server Configuration Manager. Pomyślałem sobie "raz kozie śmierć", zobaczę co się stanie jak usunę jeden z nich. Oczywiście najpierw wyeksportowałem kopię klucza, a dopiero potem go usunąłem. Okazało się to strzałem w dziesiątkę. Po tej operacji dodanie nowej przystawki w końcu zadziałało. Co ciekawe nie ma znaczenia czy usuniemy klucz przystawki dla MSSQL 2005, czy dla MSSQL 2008.

Reasumując. Jeśli operacja dodania nowej przystawki konsoli zarządzania kończy sie błędem, a masz na komputerze zainstalowane dwie (lub więcej) wersji MSSQL to z dużym prawdopodobieństwem problem spowodowany jest konfliktem pomiędzy przystawkami SQL Server Configuration Manager dla różnych wersji MSSQL. Można go rozwiązać usuwając odpowiedni wpis z rejestru. Nie jest to idealne rozwiązanie, ale z braku laku dobry kit.

14/04/2011

CURRENT_USER , SYSTEM_USER...

Home

W poście Problem z domyślnym schematem wspomniałem, że w celu wyjaśnienia problemu posłużyłem się funkcją CURRENT_USER, która zwraca nazwę bieżącego użytkownika. Czym jednak funkcja ta różni się od funkcji SYSTEM_USER, SESSION_USER czy innych o podobnych nazwach. Sprawa jest prosta. Część z tych funkcji zwraca login, który służy do uwierzytelnienie się względem serwera, a część nazwę użytkownika, która określa co możemy zrobić w ramach poszczególnych baz danych (autoryzacja). Każdy login jest skojarzony (zmapowany) z jednym użytkownikiem dla danej instancji bazy danych. Nie jest to nic skomplikowanego ale można się zgubić w gąszczu nazw. Dlatego ku pamięci, głównie dla siebie, zebrałem te informacje w postaci poniższej tabelki.

CURRENT_USERZwracają nazwę użytkownika
USER_NAME
SESSION_USER
USER

SYSTEM_USERZwracają login
SUSER_SNAME

Więcej szczegółów np.: parametry wywołania, wyjaśnienie skąd wzięło się tyle funkcji robiących to samo, można znaleźć tutaj.

13/04/2011

Problem z domyślnym schematem

Home

Kilka dni temu chciałem zmodyfikowałem domyślny schemat dla jednego z użytkowników, niech nazywa się SomeUser. W tym celu otworzyłem Management Studio, wybrałem interesującą mnie bazę danych i przeszedłem do listy użytkowników. Dalej wybrałem interesującego mnie użytkownika i wyświetliłem dla niego okno właściwość i w polu Default schema: wpisałem nazwę schematu, dla ustalenia uwagi niech nazywa się testSchema.

Żeby być pewnym, że wszystko jest w porządku nawiązałem połączenie z serwerem korzystając z wspomnianego użytkownika i spróbowałem wykonać trywialne zapytanie pobierające dane z tabeli znajdującej się w schemacie testSchema:
select *
from TestTable
Ku swojemu zdziwieniu otrzymałem komunikat o treści Invalid object name 'TestTable'. Sprawdziłem, więc zapytanie zawierające pełną nazwę tabeli (razem ze schematem) i zadziałało:
select *
from testSchema.TestTable
Aby upewnić się, że pracuję w kontekście właściwego użytkownika posłużyłem się poleceniem select current_user, które ponownie ku mojemu zdziwieniu wypisało na ekran dbo zamiast SomeUser. No cóż może się pomyliłem. Ponownie połączyłem się z serwerem upewniając się, że korzystam z dobrego użytkownika ale nic się nie zmieniło.

Problem pomógł mi rozwiązać kolega, który zwrócił uwagę, że SomeUser ma przypisaną rolę sysadmin, a więc w rzeczywistości był widziany jako użytkownik dbo (dla którego domyślny schemat to dbo). Po zabraniu użytkownikowi roli sysadmin, która nie była mu zresztą potrzebna, wszystko zaczęło działać jak trzeba.

01/04/2011

Zabawy z pozycjonowaniem okna w WPF

Home

Czasami zachodzi potrzeba "ręcznego" pozycjonowania okna w aplikacji WPF. Sprawa jest prosta i sprowadza się do odpowiedniego ustawienia właściwości Left oraz Top. Jeśli chcemy aby pozycja okna dziecka zależała od położenia rodzica to możemy odwołać się do rodzica przez właściwość Owner i napisać taki kod jak poniżej. Kod ten powoduje przesunięcie okno dziecka o 50 jednostek w prawo względem lewej krawędzi okna rodzica.
...
myWindow.Left = myWindow.Owner.Left + 50;
...
Nic prostrzego. Jest tu jednak mały haczyk. Jeśli okno rodzica jest zmaksymalizowane to właściwość Left i Top dla rodzica będą miały wartość wskazującą położenie okna przed zmaksymalizowaniem. Poniżej kod, który to uwzględnia:
...
myWindow.Left = (myWindow.Owner.WindowState == WindowState.Maximized ? 0 : myWindow.Owner.Left) + 50;
...
Nic trudnego ale trzeba o tym pamiętać. Sprawa robi się jeszcze ciekawsza kiedy pracujemy z wieloma monitorami. W takim wypadku powyższy kod będzie działał tylko dla głównego monitora. Jeśli okno rodzica będzie zmaksymalizowane i będzie znajdować się na innym monitorze niż główny to wykonanie tego kodu spowoduje wyświetlenie okna dziecka na głównym monitorze! Poniżej rozwiązanie tego problemu:

if (myWindow.Owner.WindowState == WindowState.Maximized)
{
  Screen s = Screen.FromHandle(new WindowInteropHelper(myWindow.Owner).Handle);                      
  myWindow.Left = s.WorkingArea.Left + 50;
}
else
{
  myWindow.Left = myWindow.Owner.Left + 50;
}
                    
Korzystam tutaj ze starej poczciwej klasy Screen, przy pomocy której znajduję monitor, na którym wyświetlane jest okno rodzica. Następnie odczytuję położenie lewej krawędzi tego monitora. Wartość ta będzie różna w zależności od tego, z którym monitorem mamy do czynienia.

23/03/2011

Przygody ze Steam'em

Home

Shogun: Total War to jedna z pierwszych gier jaką odpaliłem na swoim pierwszym komputerze PC i zarazem jedna z najlepszych gier w jakie grałem. Bardzo podobała mi się również inna gra z tej serii czyli Rome: Total War. Ostatnio postanowiłem nadrobić zaległości i kupiłem ostatnią grę z tej serii czyli Napoleon: Total War.

Napoleon: Total War jak wiele obecnie sprzedawanych gier wymaga do działania konta w serwisie Steam. Żaden problem ponieważ takie konto posiadam już od dawna. Niestety Steam potrafi być bardzo irytujący. Zacznę od tego, że po uruchamieniu klient Steam sprawdza czy są dostępne aktualizacje i pobiera je nie pytając użytkownika o zdanie. W tej chwili dysponuję połączeniem modemowym, a więc jest to dla mnie tym bardziej uciążliwe.

Na tym nie koniec. Zanim udało mi się uruchomić właściwy proces instalowania gry napotkałem jeszcze jeden problem. Po uruchomieniu instalatora pojawił sie błąd Failed to run install script. Szczęśliwie udało mi się go szybko rozwiązać, uruchamiając proces instalacji z wiersza poleceń przy pomocy komendy steam.exe -install h: gdzie h: to napęd DVD.

Kiedy instalacja zakończyła się i myślałem, że w końcu zagram okazało się, że Steam ma jeszcze coś do powiedzenia i rozpoczął aktualizację dopiero co zainstalowanej gry. Wyłączenie automatycznej aktualizacji we właściwościach Napoleon: Total War, odłączenie Internetu, ponowne uruchomienie klienta Steam nie pomogło. W tej chwili proces instalacji zakończył się i udało mi się uruchomić grę :) Tak sobie jednak myślę, że stare dobre czasy kiedy kupowało się grę, przychodziło do domu, instalowało i grało bez potrzeby aktywowania przez Internet, przymusowej aktualizacji itp. mijają albo już minęły.