Category Archives: Development

Visual Studio: Jak vypnout v Solution Exploreru rozbalování souborů (na třídy)

Pokud, stejně jako já, považujete možnost Solution Exploreru rozbalit strom souborů až na úroveň obsahu těchto souborů (na třídy, jejich membery, atp.), tuto funkci lze vypnout:

image

Buď si můžete nainstalovat VSCommands a použít volbu “Disable Graph Provider” nebo stačí toto nastavení v registrech (v Options Visual Studia to nenajdete):

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\12.0]
"UseSolutionNavigatorGraphProvider"=dword:00000000

…verzi Visual Studia samozřejmě upravit dle potřeby, prý to funguje už od VS2012 (11.0).

Update VS2015:

Funguje i pro VS2015, jen na konci cesty v registrech je verze 14.0.

Update VS2017:

VS 2017 navíc používá privátní registry pro každou instalovanou instanci. Je potřeba tedy najít příslušný soubor privateregistry.bin na disku a připojit do regedit do HKEY_USERS pomocí File / Load Hive… (na zvoleném jméně nezáleží). V připojené registry pak klíč přidáme a zase musíme dát Unload Hive…

Coded UI Tests: The playback failed to find the control with the given search properties.

Ve VS 2013 pomocí Coded UI Test Builderu nahrávám skript pro proklikání stránek.

Test se podaří vyrobit, ale při přehrávání dostávám výjimku:

Microsoft.VisualStudio.TestTools.UITest.Extension.UITestControlNotFoundException: The playback failed to find the control with the given search properties. Additional Details:
TechnologyName:  'Web'
ControlType:  'Hyperlink'
TagName:  'A'
Id:  ''
Name:  ''
Target:  ''
InnerText:  'Kanda Jiří'
 Failed to find any control that matched the search condition Id='' && Name='' && ControlType='Hyperlink' && Target='' && InnerText='Kanda Jiří' ---> System.Runtime.InteropServices.COMException: Volání součásti COM vrátilo chybu HRESULT E_FAIL.

Hraji si s vyrobeným kódem a zjišťuji, že problém se vyskytuje pouze tehdy, pokud se hledá pomocí podmínky na InnerText.

This.Xyz.SearchProperties[HtmlHyperlink.PropertyNames.InnerText] = "xyz";

Pokud je tato podmínka odstraněna, test začne fungovat.

Řešení, jak tento problém obejít, je neuvěřitelné a pro mě těžko pochopitelné. V PlaybackSettings je třeba nastavit vlastnost AlwaysSearchControls (což je nutné i pro další problém s Coded UI Testy) a navíc značně prodloužit DelayBetweenActions z výchozí hodnoty 100 ms.

Playback.PlaybackSettings.AlwaysSearchControls = true;
Playback.PlaybackSettings.DelayBetweenActions = 500;

Coded UI Tests: Another control is blocking the control. Please make the blocked control visible and retry the action…

Ve VS 2013 pomocí Coded UI Test Builderu nahrávám skript pro proklikání stránek na www.havit.cz. Test se podaří vyrobit, ale při přehrávání dostávám výjimku:

Microsoft.VisualStudio.TestTools.UITest.Extension.FailedToPerformActionOnBlockedControlException: Another control is blocking the control. Please make the blocked control visible and retry the action. Additional Details:
TechnologyName:  'Web'
ControlType:  'Hyperlink'
TagName:  'A'
Id:  ''
Name:  ''
Target:  ''
InnerText:  '…'
 ---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0xF004F003

Na internetu se tomuto problému věnují obsáhlé diskuse, většinou okolo VS 2012 a IE9/10. Většina doporučených řešení spočívá v odinstalaci IE10, odinstalaci patche KB2870699 nebo instalaci VS 2012 Update 4. Některé řešení většině zabírá.

My jsme však o verzi dále – VS 2013 a IE 11, kde žádné z předchozích řešení nefunguje. Chyba se shodně projevuje na šesti ze sedmi počítačů, nepůjde tedy o náhodný problém s jedním počítačem. Shodou náhod reinstaluji jeden starý stroj, zkouším tedy čistou instalaci (Windows 7, Internet Explorer 11, Visual Studio 2013, kompletní aktualizace Windows Update) a ověřuji, že problém se objevuje i zde.

Výjimka říká, že se nepodařilo na control kliknout, že je z nějakého důvodu blokovaný. Pokud zkusím zobrazit místo, kde se control nachází (metodou DrawHightlight() ), je místo označeno správně, takže se domnívám, že v hledání controlu by neměl být problém a mělo by jít skutečně o problém přehrávání. K mému překvapení zabírá řešení, které čistě náhodně zkouším – nastavení AlwaysSearchControls na true.

Playback.PlaybackSettings.AlwaysSearchControls = true;

SQL Server ignoruje DEFAULT_SCHEMA pro uživatele v roli sysadmin

SQL Books online (dnes vlastně TechNet nebo spíš už dokonce MSDN) jsou nekompromisní:

The value of DEFAULT_SCHEMA is ignored if the user is a member of the sysadmin fixed server role. All members of the sysadmin fixed server role have a default schema of dbo.

Primárně je samozřejmě špatně se na DEFAULT_SCHEMA spoléhat, nicméně při práci na starším projektu mě to překvapilo, když jsem dal uživateli sysadmin roli a najednou mi to přestalo nacházet objekty v DB.

WatiN: Could not load file or assembly Interop.SHDocVw

Pokud by vás WatiN po instalaci z NuGetu obšťastnil hláškou ve stylu

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembl y ‚Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=db7cfd3acb5 ad44e‘ or one of its dependencies. The located assembly’s manifest definition do es not match the assembly reference. (Exception from HRESULT: 0x80131040) File name: ‚Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=db

…pak je potřeba na referenci Interop.SHDocVw nastavit v Properties volbu „Embed Interop Types“ na false:

imageimage

Jinak si zkouším hrát s WatiN-em. Máte s tím někdo zkušenosti? Výhody/nevýhody proti Visual Studio Coded UI Test (mimo licenčních)?

IIS Express: Managed Pipeline Mode – Classic

Pokud je Vaše aplikace psána pro Classic Managed Pipeline Mode, potom při standardním spuštění nad IIS Expressem dostanete krásnou chybku:

HTTP Error 500.22 – Internal Server Error

An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode.

image

Mě to potkalo u přechodu z VS2012 (kde jsem aplikaci pouštěl nad vestavěným Cassini) na Visual Studio 2013, kde je již jenom IIS Express. Přepínač je lehce ukryt, najdete ho v Properties projektu webové aplikace:

image

SQL DMV: Most Expensive Queries, Missing Indexes

Kolem Database Management Views a jejich využití pro SQL performance diagnostics toho napsáno tuny, ale právě tato kvanta různých zdrojů uvádějí spousty různě kvalitních podob dotazu pro Most Expensive Queries.

Nebaví mě pokaždé hledat ten správný, nebo ho dokonce vymýšlet, proto si zde archivuji mojí oblíbenou podobu:

-- Most expensive queries
SELECT TOP 20
	SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1,
		((CASE qs.statement_end_offset
			WHEN -1 THEN DATALENGTH(qt.TEXT)
			ELSE qs.statement_end_offset
			END - qs.statement_start_offset)/2)+1)
		AS query_text,
    db.name AS [db_name],
    qs.total_elapsed_time/1000 AS total_elapsed_time_ms,
    qs.total_elapsed_time/qs.execution_count/1000 AS average_elapsed_time_ms,
    qs.last_elapsed_time/1000 AS last_elapsed_time_ms,
    qs.execution_count,
    qs.total_worker_time/1000 AS total_worker_time_ms,
    qs.total_worker_time/qs.execution_count/1000 AS average_worker_time_ms,
    qs.last_worker_time/1000 AS last_worker_time_ms,
    qs.last_execution_time,
    qs.total_logical_reads,
	qs.last_logical_reads,
    qs.total_logical_writes,
	qs.last_logical_writes
    --qp.query_plan
    FROM sys.dm_exec_query_stats qs
        CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
        CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
        LEFT JOIN sys.databases db ON (qt.dbid = db.database_id)
    -- WHERE db.name='DatabaseName'
    -- ORDER BY qs.total_logical_reads DESC
    -- ORDER BY qs.total_logical_writes DESC
    -- ORDER BY qs.last_worker_time DESC -- CPU time (active)
    -- ORDER BY qs.last_elapsed_time DESC -- clock time (včetně čekání na locky, atp.)
    -- ORDER BY qs.total_worker_time DESC
	ORDER BY qs.total_elapsed_time DESC

…a rovnou přidávám už méně používaný dotaz pro chybějící indexy (varuji před zkratkovitou úvahou, že tyto indexy je nutné přidat):

SELECT
	mid.statement
	  ,migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure,OBJECT_NAME(mid.Object_id),
	  'CREATE INDEX [missing_index_' + CONVERT (VARCHAR, mig.index_group_handle) + '_' + CONVERT (VARCHAR, mid.index_handle)
	  + '_' + LEFT (PARSENAME(mid.statement, 1), 32) + ']'
	  + ' ON ' + mid.statement
	  + ' (' + ISNULL (mid.equality_columns,'')
		+ CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END
		+ ISNULL (mid.inequality_columns, '')
	  + ')'
	  + ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement,
	  migs.*, mid.database_id, mid.[object_id]
	FROM sys.dm_db_missing_index_groups mig
		INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle
		INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle
	WHERE migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) > 10
	ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC

Visual Studio 2013 RTM ke stažení z MSDN

Visual Studio 2013 je ke stažení z MSDN, není co dodat.

Optimalizace webových aplikací ASP.NET – záznam, slide a dema [MS Fest 2013]

Slide (jeden) a dema z mé dnešní přednášky pro MS Fest 2013 v Brně:

Z přednášky se pořizoval záznam, který najdete na našem HAVIT YouTube Channel:

Databáze zůstane viset ve stavu „Restoring“

Pokud Vám zůstane databáze z jakéhokoliv důvodu viset ve stavu Restoring, znamená to, že sled předcházejících událostí SQL server interpretoval jako nedokončenou snahu o obnovení databáze. Legitimně se v tomto stavu databáze nachází, pokud chcete např. přehrát nad obnovenou zálohou ještě transaction-logy, atp.

Pokud tento stav pro Vás není žádoucí, nic dalšího už nechcete udělat a potřebujete databázi oživit, potom pomůže

RESTORE DATABASE MyDatabase WITH RECOVERY

…kde MyDatabase pochopitelně nahradíte názvem své DB.