WinDbg: Trvalá změna výchozího fontu popř. dalších nastavení

WinDbg (Windows Debugger) má svá specifika. Představuji si to asi tak, že když už byl příslušný tým v Microsoftu po několika marných pokusech dotlačen k vytvoření GUI nad konzolovou podobou (jedinou pravověrnou), rozhodl se to udělat tak, aby vzniklá GUI nadstavba opravdu nikoho nelákala se do debuggingu na této nízké úrovni pokoušet.

Jedním ze specifik tak například je, že zatímco v každé jiné aplikaci pokud změníte velikost písma a podobné volby UI, pamatuje si to aplikace i do příštího spuštění, aniž byste to museli nějak řešit.

Ve WinDbg tomu tak není.

Dlouho jsem si dokonce myslel, že to nějak souvisí s novými vymoženostmi ve Windows ála UAC, které nedovolí zastaralému WinDbg uložit nastavení do Program Files nebo nějakého jiného chráněného místa, kam si natavení chce persistovat.

Není tomu tak.

Windows Debugger totiž má logiku svojí – konkrétní nastavení UI je zabaleno do podoby Workspace (mimo fontu je tam i layout oken a spousta dalších věcí). Workspaces můžeme mít více a můžeme mezi nimi přepínat (mimochodem VS2015 přišlo s layouty, implementováno však příčetněji).

Záludnost je v tom, že výchozí nastavení WinDbg má vypnuté ukládání změn Workspace. Tedy cokoliv nastavíme, tak se vypnutím WinDbg zapomene, aniž by se to na cokoliv zeptalo. Mám dokonce pocit, že toto se v průběhu verzí muselo změnit, protože kdysi se mě WinDbg při ukončování na změnu Workspace ptal.

Jak tedy font změnit, aby si to WinDbg do příště zapamatoval?

  1. Otevřeme WinDbg (neotevíráme žádný dump ani jinou debugging session).
  2. V Menu File zvolíme Save Workspace (změna by se měla uložit do default Workspace).
  3. Vystoupit, nastoupit, font by se měl pamatovat.

Změna se kupodivu projeví i v X64 i X86 verzi WinDbg.

Pokud by to kladlo nějaký odpor

  • Přes View / Options / Worspace Prompts = Always Ask povolíme dotazy na uložení změn Workspace
  • Přes File / Delete Workspaces… můžeme vyházet nežádoucí workspaces (klidně všechny :-))

…mno, jak jednoduché, už nebudu muset s každým spuštěním znovu nastavovat font přiměřený své slepotě, resp. vhodný pro prezentaci.

Na iPhone se zobrazuje počet nepřečtených emailů, přestože jsou přečteny všechny

Přestože mám na iPhone úplně prázdnou mailovou schránku, zobrazuje se na ikonce mailu odznak s počtem nepřečtených emailů.

Postup, který to řeší je jednoduchý:

  • V nastavení účtu vypnout synchronizaci pošty
  • Restartovat telefon
  • Zapnout synchronizaci pošty

Zdroj: https://www.youtube.com/watch?v=gF08XGixErY

Visual Studio: Úprava snippetu „ctor“, aby kurzor po rozbalení skončil v místě pro zadávání parametrů

Pokud používáte snippet „ctor“ pro vytváření konstruktorů tříd, může vás štvát, že kurzor po jeho rozbalení skončí připraven v těle konstruktoru a nikoliv v místě pro zadávání parametrů.

ctor1

Drtivá většina constructorů v dnešní době stejně pouze přebírá hodnoty parametrů, které uloží do lokálních privátních fieldů. Často readonly, většinou jako dependencies v patternu Constructor Injection z rodiny Dependency Injection. Takové konstruktory se poměrně efektivně vytvářejí s použitím akce „Introduce and initialize field“ na zapsaném parametru (ať už za použití Resharperu, nebo Introduce and initialize field extension).

expand

Chceme-li změnit pozici kurzoru, stačí upravit snippet ctor a umístit marker $end$ na místo, kde chceme kurzor připravit.

Pokud máme Resharper, dostaneme se na editaci snippetu přes menu Resharper ~ Tools ~ Templates Explorer. Vybereme scope C# a editujeme „ctor“:

public $classname$ ($END$)
  {
	    
  }

Bez Resharperu je potřeba editovat přímo soubor snippetu na disku, najdete ho v cestě C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC#\Snippets\1033\Visual C#\ctor.snippet. Je to krátké XML v kterém příslušný blok rychle najdete.

Výsledné chování je pak mnohem přímočařejší:

full

API restriction: The assembly “file:///…Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll‘ has already loaded from a different location. It cannot be loaded from a new location within the same appdomain.

Pokud se s touto chybou potkáte ve Visual Studiu, nejspíš se vám podaří něco kolem toho vygooglit. Zákeřnější je tato chyba na TFS Build Serveru, kde jsou postupy nalezené k většinou VS irelevantní.

Obvyklou příčinou je, že se vám na Build serveru spouští při testech něco víc, než plánujete.

Například

  • patternu pro assemblies s unit-testy odpovídá i jiný projekt, v mém případě např. TestHelpers.dll se sdílenými pomůckami nečekaně spadl do výchozího patternu „*test*.dll“, který na konkrétním buiĺdu nebyl změněn za námi používanou konvenci „*Tests.dll“. Můj TestHelpers.dll referencuje také Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll a chyba byla na světe.
  • pattern pro assemblies s unit-testy najde vaše testy vícekrát v různých složkách. Pomoct by mělo změnit pattern  z „**\*test*.dll“ na „*test*.dll“, aby se obešel folder-matching.

Vzdálené spouštění testů se nedaří: Failed to queue test run ‚…‘: A connection attempt failed…

Problém: Na build serveru (TFS 2015) spouštíme v rámci buildu unit testy. Testy jsou spouštěny vzdáleně na test serveru (test controller / test agent). Spuštění testů se nezdaří, dostáváme chybu „Failed to queue test run ‚…‘: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.“

Řešení: Ve Windows Firewallu stroje, který vzdáleně spouště testy, povolit komunikaci programu C:\ProgramFiles (x86)\Microsoft Visual Studio 14.0\Common7\IDE\MSTest.exe.

Zdůrazňuji, že konfigurujeme volající stranu (build server), nikoliv volanou stranu (test server).

Zdá se, že nám výskyt tohoto problému souvisí s instalací Visual Studia 2015. Instalátor sice do firewallu několik pravidel přidal, nicméně ta nedostačovala.

Programátorská hádanka: ArgumentException, ArgumentNullException

Přijde vám na následujícím kódu něco divného?

public void DoSomething(MyClass firstParameter)
{
  if (firstParameter == null)
  {
    throw new ArgumentNullException(nameof(firstParameter), "My message.");
  }
  if (firstParameter.SomeProperty < 0)
  {
    throw new ArgumentException(nameof(firstParameter), "My other message.");
  }

  // do something...
}

Moq: Partial mocking + cross-project internal

Není to sice ideální, ale někdy tomu situace dá, že potřebuji testovat metodu, která by jinak byla private. V takovém případě ji dělám internal a do testovacího projektu ji zpřístupňuji pomocí global atributu InternalsVisibleTo z AssemblyInfo.cs:

[assembly: InternalsVisibleTo("Havit.Xy.ServicesTests")]

To všechno funguje celkem v pohodě až do okamžiku, než se pustíte do partial-mockingu. Máme například následující třídu, kterou chceme testovat

public class TestedClass
{
  public virtual void Process()
  {
    foreach (var item in ...)
    {
      ProcessItem(item);
    }
  }

  internal virtual void ProcessItem(string item)
  {
     ...
  }
}

Dokud testujeme samotnou třídu, je vše v pohodě:

var sut = new TestedClass();
var output = sut.ProcessItem(input);

Zajímavé to začne být, pokud začneme tvořit partial-mock, tedy chceme část funkčnosti třídy nasetupovat jinak, abychom testovali jen určitou část. Třeba chceme testovat Process() bez ProcessItem():

// arrange
var sut = new Mock();
sut.Setup(sut => sut.ProcessItem(It.IsAny()).Returns(String.Empty);
sut.CallBase = true;

// act
sut.Process();

// assert
...

Najednou zjistíte, že Moq nový setup metody ProcessItem ignoruje a volá stále původní implementaci. Žádný problém navíc nehlásí a já se jen nestačím divit, co se kde hnojí.

Pak vám to najednou docvakne. Vše začne fungovat, pokud setupovanou metodu ProcessItem uděláte protected internal:

public class TestedClass
{
  public virtual void Process()
  {
    foreach (var item in ...)
    {
      ProcessItem(item);
    }
  }

  protected internal virtual void ProcessItem(string item)
  {
     ...
  }
}

…najednou vše funguje.

Programátorská hádanka: Statický field na generické třídě

Co myslíte, že je v Member v jednotlivých případech?

class BaseClass<T>
{
	public static string Member;
}

class DerivedClass1 : BaseClass<int>
{
}

class DerivedClass2 : BaseClass<double>
{
}

class DerivedClass3 : BaseClass<int>
{
}

void Main()
{
	DerivedClass1.Member = "test";
	Console.WriteLine(DerivedClass1.Member);
	Console.WriteLine(DerivedClass2.Member);
	Console.WriteLine(DerivedClass3.Member);
}

MsDeploy s NTLM zabezpečením

Nasazuji aplikace pomocí WDP na server (Windows Server 2008). Pokud msdeploy.exe předám v argumentech authType=basic a dále username a password, které používám pro přihlášení, vše funguje. Tím mám ověřeno, že můj účet má oprávnění, existuje website, atp. Nechci však psát své heslo a rád bych využil integrovaného zabezpečení.

Proto z příkazové řádky vynechávám username i password a nastavuji authType=ntlm. Pokus o nasazení aplikace se nedaří, jsem odmítnut (unauthorized).

Po drobném bádání dohledávám, že Windows autentizace je pro službu wmsvc standardně vypnutá a musí se zapnout v registrech: Pod HKEY_LOCAL_MACHINE\Software\Microsoft\WebManagement\Server je potřeba vložit DWORD klíč WindowsAuthenticationEnabled s hodnotou 1. A restartovat službu wmsvc.

Poté je již možné se k serveru připojit s využitím NTLM.

 

VS2015: Window Layout Management

Ač jsem dříve pracoval s více monitory, opustil jsem takový setup a po dlouhých rocích s 24″ 1920x1200px jsem dnes přešel (zatím „na zkoušku“) na 32″ panel 2560x1440px (Samsung S32D850T).

Rázem se ukázalo, že přechod mezi zadockovaným notebookem a jeho vlastním 1920×1080 nebude bezbolestný jako dosud, že uspořádání Visual Studia už bude potřeba nějak přepínat.

Pro starší verze VS byl potřeba doplněk, např. Layouts O Rama, ve Visual Studio 2015 je již vestavěno:

image

…synchronizuje se dokonce přes Microsoft Account, není již co řešit.