Author Archives: Jiří Kanda

TFS (XAML) Builds – Jak vytvořit lokální workspace

TFS (XAML) Build vytvoří workspace na build serveru, do něj stáhne zdrojové kódy a ty kompiluje. Workspace vytváří aktivita CreateWorkspace, která vytvoří serverový workspace a není způsob, jak této aktivitě říct, aby vytvořila workspace lokální. Aktivita CreateWorkspace navíc vrací instanci reprezentující založený workspace.

Když tedy nelze při říct, že založený workspace má být lokální, lze použít drobný workaround – založit workspace jako serverový a dodatečně jej přepnout na lokální. To lze provést zavoláním metody Update na instanci vrácené z CreateWorkspace. V rámci TFS (XAML) Buildu to můžeme udělat reflexí, tedy aktivitou InvokeMethod s těmito parametry:

  • Target Object: Workspace (resp. taková proměná, ve které máme vrácenou instanci z activity CreateWorkspace)
  • Method Name: Update
  • Parameters: In / Microsoft.TeamFoundation.VersionControl.Client.UpdateWorkspaceParameters / New UpdateWorkspaceParameters With { .Location = Microsoft.TeamFoundation.VersionControl.Common.WorkspaceLocation.Local }

O rozdílech mezi lokálním a serverovým workspacem si můžete přečíst tady nebo tady. Naše touha pro přechod ze serverového na lokální workspace byla vedena přiblížením prostředí buildu vývojářskému prostředí, zejména nenastavení read-only atributů na stažených souborech.

 

Quartz.NET a úplné vymazání plánu

Quartz.NET je plánovač spouštění úloh v rámci procesu aplikace. Úlohy se plánují tak, že se vytvoří Job (spouštěná úloha) a k němu triggery (kdy se spouští). Quartz.NET umí navíc plány perzistovat do databáze, což může být šikovné k tomu, aby se úloha plánu spustila i tehdy, pokud aplikace v okamžiku, kdy měla být úloha spuštěna, z jakéhokoliv důvodu neběžela – misfire. Obdobně umožní spustit job, který z nějakého důvodu nedoběhl (pád, vypnutí stroje) – recovering.

Tím, že je plán perzistentní, není vhodné jej vytvářet se při každém startu aplikace, protože tím by úplně přišlo o výhody perzistence. Plán vytváříme pouze při aktualizaci aplikace.

Existující plán se smaže Clear na Scheduleru – scheduler.Clear(). Problémem však je, že toto nesmaže plán recovering jobů. Nikdy. Pokud tedy takto smažeme plán a vytvoříme nový, plán recovering jobů zůstává zachován. Po nastartování plánovače jsou recovering joby okamžitě spuštěny.

Řešením může být rozšíření metody ClearData třídy SqlServerDelegate (pokud je perzistováno do SqlServeru touto třídou). Tato metoda je volána pod pokličkou v rámci volání scheduler.Clear(). Rozšíříme ji o volání metody DeleteFiredTriggers.


public class MySqlServerDelegate : SqlServerDelegate

{

    public override void ClearData(ConnectionAndTransactionHolder conn)

    {

        base.ClearData(conn);

        DeleteFiredTriggers(conn);

    }

}

Dále musí být scheduleru řečeno, že má tuto třídu používat. Při použití rozšíření Quartz.NET o intergraci s Windsor Castle pomocí NuGet balíčku Quartz.Windsor se název typu s assembly uvádí v konfiguraci pod klíč


<item key="quartz.jobStore.driverDelegateType">...</item>

Code Analyzers vs. generovaný kód

Pomocí analyzérů ve VS 2015 máme možnost kontrolovat programový kód různými pravidly ověřující štábní kulturu kódu. Netestuje se tedy, zda kód dělá to, co má, ale zejména to, jak je zapsán. Ale i to dokáže občas odhalit chyby v chování programu.
V aplikacích je však nejen kód ručně psaný programátory, ale často i kód generovaný různými nástroji (designer soubory od resources, aspx, atp.)

Takový kód často nesplňuje pravidla, které na vlastní kód klademe, a zároveň nemáme možnost způsob generování ovlivnit.

Jedno možností je použít global suppressions (viz Code Analysis na stránce https://www.visualstudio.com/en-us/news/vs2015-update1-vs.aspx), druhou možností je vypnout kontrolu generovaného kódu ve vlastnostech projektu.

codeanalysis

To však přináší zmatek v tom, co který analyzér považuje za generovaný kód. Pro určení, zda jde o generovaný kód používají různé nástroje různé techniky, například

  • dle pojmenování souboru
  • dle obsahu souboru – komentář s <auto-generated />
  • nebo dle obsahu souboru – attributy u třídy

StyleCop Analyzers

Jako generovaný kód označují kód souboru (zdroj):

  • jehož název končí na .designer.cs
  • nebo obsahuje v komentáři text <auto-generated či <autogenerated
  • nebo je soubor prázdný.

SonarLint for Visual Studio 2015

Jako generovaný kód označují kód (zdroj):

  • souboru, jehož název obsahuje .g., .generated., .designer., .generated., _generated. nebo temporarygeneratedfile_
  • nebo obsahuje v komentáři text <auto-generated či <autogenerated
  • nebo je třída odekorována atributem DebuggerNonUserCode, GeneratedCode, ExcludeFromCodeCoverage či CompilerGenerated.

Code Analyzers

Neobsahují žádnou logiku pro odlišení generovaných souborů od ostatních (nebo se mi ji alespoň v čase, který jsem hledání byl ochoten věnovat, žádnou nenašel).

(zdroj)

Srovnání analyzérů

Tabulka ukazuje, které analyzéry považují jaký soubor za generovaný (ano = generovaný, ne = nerozpoznáno):

.designer.cs
(název souboru)
// <auto-generated>
(obsah souboru)
[GeneratedCode]
(obsah souboru)
Code Analyzers  ne ne ne
StyleCop Analyzers ano ano ne
Sonar Lint ano ano ano

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

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.

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.

 

Azure Powershell – nejsou vidět subscriptions

Dnes jsem narazil na situaci, kdy jsem v powershellu neviděl subscriptions, které jsem měl dříve k dispozici. Nepomáhalo ani Add-AzureAccount, ani odebrání (všech) accountů a jejich opětovné přidání.

Jako řešení zafungovalo smazání složky C:\Users\USERNAME\AppData\Roaming\Windows Azure Powershell, ve které jsou standardně uloženy “Subscription Data Files”.