Exchange Shell: Skript pro přesun public folders mezi dvěma Exchange servery (Replicas)

Potřebovali jsme přesunout veřejné složky (Public Folders) mezi dvěma Exchange servery, konkrétně z 2007 na 2010.

Postupů je na netu k nalezení mraky, nicméně obecně je jako jeden z kroků potřeba naklikat všem složkám nebo naskriptovat změnu Replication z jednoho serveru na druhý (z jedné DB na druhou).

Mělo by to jít pomocí skriptu MoveAllReplicas.ps1, z kterého se volá ReplaceReplicationOnPFRecursive.ps1, nicméně nám se tyto skripty v připravené podobě rozchodit nepodařilo.

Inspirovali jsme se však jejich obsahem a tak vzniknul níže uvedený primitivní skript na přenastavení všech replikací na cílový server:

$dbNew = get-publicfolderdatabase -server $newServer -erroraction Stop
$getpfcmd = "get-publicfolder -server $oldServer -identity $TopPublicFolder -Recurse -resultsize unlimited"

$tempik = invoke-expression $getpfcmd
$tempik | foreach {
    $_.Name;
    $_.Replicas.Clear();
    $_.Replicas += $dbNew.Identity;

    $_ | set-publicfolder -server $oldServer -replicas $_.Replicas
}

…výše uvádím snippet kódu, který představuje podstatnou výkonnou část. Před spuštěním je potřeba nastavit $oldServer, $newServer a $topPubliFolder (obvykle na zpětné lomítko).

ASP.NET Device Filters

Nedávno se mi připomněla jedna starší lahůdka (čti obskurnost, za kterou může ten zpropadený svět heterogenních browserů) – Device Filters. Dovolím si tedy připomenout:

Jde o víceméně elegantní deklaratorní zápis, jak nastavovat různé hodnoty jednotlivých properties controlů a direktiv v ASP.NET v závislosti na browseru. Syntaxe je jednoduchá:

<asp:Label IE:Text="Používáte Internet Explorer" Mozilla:Text="Používáte Firefox" PIE:Text="Používáte Pocket IE" Text="Používáte Buchvíco" runat="server" />

Není to jen o properties controlů, dá se to použít i pro direktivy, takže například pro <%@ Page %> lze nastavit MasterPageFile či Theme. Rozpoznávané browsery se řídí browser-definition-files (App_Browsers, browserCaps).

ASP.NET Sprite and Image Optimization Framework

Že Microsoft ASP.NET team si už delší dobu hraje s věcmi kolem CSS Sprites se vědělo už dlouho. Nakonec nečekají na další release ASP.NET a uvolnili svůj ASP.NET Sprite and Image Optimization Framework už nyní (na Codeplex). Pokud tedy chcete na svých webech optimalizovat rychlost načítání a zobrazování obrázků, určitě doporučuji Vaší pozornosti. Kdo netušíte, o co jde, potom viz instruktážní video (ve zkratce jde o slučování několika obrázků do jednoho a zobrazování výřezů z něj na Vaší webové stránce pomocí CSS stylování s background-image).

VS2010 – Lokalizace do češtiny ke stažení

V rámci snahy o zpřístupnění vývojářských nástrojům „širokým masám“ uvedl dnes Microsoft další ztřeštěnost -Jazykovou sadu pro češtinu, která Vám umožní přepnout prostředí Visual Studia 2010 Professional do češtiny. Lokalizační sada je ke stažení ze stránek MSDN.cz.

Tož přeji hodně štěstí těm, co se při svém prvním sestavení řešení (build solution) dostanou až k sestavení (assembly). Osobně odmítám komunikovat s kýmkoliv, kdo by na mě zkoušel tento kryptojazyk použít a důrazně vyzývám všechny, aby si před komunikací se mnou zjistili anglickou podobu, chtějí-li se vyhnout mému podezření, že jsou marťani.

Osobně mi jako výrazně lepší nápad pro jazykově méně vybavené přišel nástroj CLIP (Captions Language Interface Pack) pro VS2008, který zobrazoval překlady až na najetí myši na danou část UI.

Notes on VS2010 Advanced Debugging

Koukám na zajímavou session (sérii) na téma Techniques on Advanced Debugging a nedá mi to, abych si z toho neudělal pár „účastnických“ poznámek pro mé kolegy. No a když už si je píšu, tak je dávám k dispozici, třeba to někomu přijde vhod:

Doporučuje se
  • Vypnout přepínač „Just my code“ v Options/Debugging (umožní ladit i Release code a spoustu dalších věcí, které jinak nejsou možný)
  • Vypnout přepínač „Enable the Visual Studio hosting process“ (= MyApp.vshost.exe, slouží ke zrychlení zavádení procesu, ale má i nepříjemné side effecty)
Triky
  • pomocí Open Project/Solution se dá otevřít .EXE (!!) soubor a následně ho debuggovat (až už F5 nebo Attach to process)
    • chce to mít .PDB soubory symbolů
    • v Properties od solution se dá nastavit v Debug Source Files, kde jsou zdrojáky, pokud nenastavím a nenajde je v původní cestě dle PDB souboru, tak se zeptá na cestu během ladění (pokud mu ji nedám, udělá disassembly do MSIL)
  • v Call Stacku lze nastavit Break Point (F9), který se nastaví při návratu na dané místo
  • lze nastavit Break Pointy pouze na některou část řádku (např. v cyklech for/foreach/do-while zvlášť na vstup do cyklu, zvlášť na inicializaci, zvlášť na vyhodnocení podmínek, atp.); stačí pravým/F9 kliknout na danou část řádku a vložit BP tam
  • Pokud dělám in-line watch (data tip) a zobrazené hodnoty mi překrývají kód, který chci vidět, stačí zmáčknout Ctrl a dokud ho držím, potom watch-box zprůhlední
  • v in-line watch-boxu (data tip) se dá pravým tlačítkem vyvolat contextové menu a třeba tak přidávat do Watch Window zanořená pole, která chci sledovat
  • v in-line watch-boxu (data tip) se dají hodnoty editovat (měnit za běhu hodnoty proměnných), stejnětak ve Watch panelu 
  • do Watch Window se dají přidávat řádky (výrazy) drag&dropem z kódu
  • v Immediate Window se dá během přerušení debuggeru spouštět vlastní kód, vyhodnocovat metody, atp., zahájíme-li řádek otazníkem, dostáváme hodnotu výrazu
  • Make Object ID (pravým na data tip/watch) – objekt dostává referenční číslo (např. „1#“) a je pak možné sledovat jeho hodnotu i mimo původní scope viditelnosti a třeba udělat i instanční podmínku „this == 1#“ do Breakpoint Condition, nebo se dozvědět o tom, že byl garbage-collected (stále observuji určitou referenci v paměti, něco jako WeakReference)
  • ve Watch Window můžu používat pseudo-variables
    • $user – aktuální identita threadu + processu
    • $exception – aktuální výjimka
  • Set Next Statement – pokud debuguji, tak mi žlutě svítí řádek, který se má jako další vykonat, vlevo od něj je žlutá šipka, pokud tuhle šipku přetáhnu na jiný řádek, přesune se mi vykonávaný kód tam (aniž by mezi tím bylo cokoliv spuštěno, prostě takový jump do neznáma, obvykle se může hodit, pokud chceme něco přeskočit); skákat se dá nejenom dopředu, ale i dozadu
  • Remote Debugging je stále omezen na tutéž doménu nebo two-way trust
Tipy
  • pokud Visual Studio dělá ptákoviny, padá na určitém projektu, nechce ho debuggovat, nebo ignoruje Break Pointy, potom stojí za zkoušku smazat (nebo alespoň na zkoušku někam přesunout) soubor .suo (uživateské nastavení solution, hidden file ve stejné složce jako .sln), nemusí to být ono, ale občas se stane, že se tenhle soubor poruší a pak se může dít výše uvedené (nejdřív samozřejmě zkusit restart VS, popř. PC)

MSBuild na x64 nepracuje správně s Code Contracts + how to fix (Updated)

Máte-li samostatný build-server na x64 platformě, na něm nainstalované Code Contracts a pouštíte 64-bitový MSBuild, potom rychle zjistíte, že takový build ignoruje Code Contracts.

Problém je v tom, že do msbuildu se nanaimportují targets pro Code Contracts (C:\Program Files (x86)\Microsoft\Contracts\MsBuild\v3.5\Microsoft.CodeContracts.targets), protože Code Contracts se nainstalují do „Program Files (x86)“ složky, kdežto 64-bitový MSBuild si nastaví property MSBuildExtensionsPath na „Program Files“ a tam Code Contracts nainstalované nejsou.

Microsoft.CodeContracts.targets se dostávají do MSBuildu přes Custom.After.Microsoft.Common.targets, které se linkují z Microsoft.Common.targets – tam je však cesta k nim sestavena přes property MSBuildExtensionsPath a ta má pro 64-bitový MSBuild hodnotu „C:\Program Files\MSBuild\“ a ne „C:\Program Files (x86)\MSBuild\“.

Problém se dá vyřešit buď používáním 32-bitového MSBuildu, nebo násilným přepsáním hodnoty MSBuildExtensionsPath na „C:\Program Files (x86)\MSBuild\“ v souboru c:\Windows\Microsoft.NET\Framework64\v3.5\Microsoft.CodeContracts.targets takto:

<PropertyGroup>

    <!-- HAVIT: Workaround oprava ConnectID 109232 -->
    <MSBuildExtensionsPath>C:\Program Files (x86)\MSBuild\</MSBuildExtensionsPath>
    <!-- HAVIT: end -->

<CustomBeforeMicrosoftCommonTargets Condition="'$(CustomBeforeMicrosoftCommonTargets)'==''">$(MSBuildExtensionsPath)\v3.5\Custom.Before.Microsoft.Common.targets</CustomBeforeMicrosoftCommonTargets>
<CustomAfterMicrosoftCommonTargets Condition="'$(CustomAfterMicrosoftCommonTargets)'==''">$(MSBuildExtensionsPath)\v3.5\Custom.After.Microsoft.Common.targets</CustomAfterMicrosoftCommonTargets>
<ReportingServicesTargets Condition="'$(ReportingServicesTargets)'==''">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\ReportingServices\Microsoft.ReportingServices.targets</ReportingServicesTargets>
</PropertyGroup>

Problém samozřejmě může nastat, až jiné build-extense než Code Contracts použijí C:\Program Files\MSBuild\ a celé se to rozjede.

Dle hlášeného bugu na Connectu však stejný problém je i s WCF, takže si myslím, že soudruzi v Microsoftu někde přecijenom dělají chybu.

Web Deployment Project + Update

Prakticky identický problém jsem řešil s beta verzí Web Deployment Projectu pro VS2010, nakonec jsem se vykašlal na úpravy souborů a prostě jsem sesynchronizoval obsah C:\Program Files\MSBuild\ se složkou C:\Program Files (x86)\MSBuild (překopíroval jsem jedno přes druhé a vice versa).

Nyní s vydáním RTW verze Web Deployment Projectu jsem si všimnul, že je toto již řešeno použitím propert $(MSBuildExtensionsPath32), která vede do správného místa. V Code Contracts by tedy mělo stačit změnit „všechny“ $(MSBuildExtensionsPath) na $(MSBuildExtensionsPath32), ale nezkoušel jsem to zatím.

TransformXml – MSBuild task pro transformaci XML souborů ála web.config transformace (XDT)

Uff, dalo mi hodně práce vymyslet titulek tohoto článku, aby alespoň trochu vyjadřoval, co článek popisuje – tedy jak pomocí nové techniky Visual Studia 2010 pro web.config transformace, tedy pomocí transformačních XDT souborů (XML Document Transformation Engine), transformovat libovolný jiný XML soubor jako součást běžného buildu.

Pokud nevíte, jak fungují ve Visual Studiu 2010 transformace web.config souborů při deploymentu, podívejte se na můj screencast na MSTV (12:48 minut) nebo na materiály z prezentací (vč. demokódu). Pokud Vás zajímá, jak tímto způsobem transformovat libovolný jiný XML soubor (ať už .config, .sitemap, nebo jakýkoliv jiný .xml), potom čtěte dále.

TransformXml MSBuild task

Celé kouzlo spočívá ve využití připraveného TransformXml MSBuild tasku, který je použit i v připraveném targetu TransformWebConfig používaném při deploymentu webových aplikací (vytváření Package). Task TransformXml je prostý, má tři parametry a vypadá takto:

<TransformXml Source="path/original.xml" Transform="path/transformation.xml" Destination="path/transformed.xml" />

Abyste však tento task mohli použít v libovolném projektovém (.csproj, .vbproj, …) souboru (nejenom tedy webu, ale i ConsoleApplication, ClassLibrary, či čehokoliv jiného mimo WebSite), musíte jej importovat instrukcí using z assembly webového deploymentu:

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>

No použít task můžete samozřejmě v rámci libovolného targetu, celé to pak může v .csproj souboru vypadat takto:

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>
<Target Name="AfterBuild">
    <TransformXml Source="Menu\default.xml" Transform="Menu\MyTransform.xml" Destination="Menu\MyMenu.xml" />
</Target>

Target AfterBuild je připravený a automaticky spouštěný po základním buildu projektu. Znáte-li fungování projektových souborů a MSBuildu, dále číst nemusíte.

Editace projektových souborů (.csproj/.vbproj/.*proj)

Projektové soubory, jak je znáte z Visual Studia, nejsou ve skutečnosti nic jiného, než MSBuild instrukční soubory, které nejenom drží pohromadě konfiguraci Vašeho projektu, ale představují především zadání pro MSBuild, jak má Vás projekt v různých situacích buildovat.

Nebojte se tedy s těmito soubory pracovat a editovat je! Nejedná se o žádné hackování Visual Studia, ale o zamýšlený způsob ovládání Microsoftího build-procesu. Visual Studio pro Vás tyto soubory typicky založí, během práce s projektem je aktualizuje, nicméně je nepřegenerovává, ale pouze edituje a je opravdu na Vás, pokud chcete buildování Vašeho projektu nějak obohatit, abyste s těmito XML soubory pracovali.

Podrobnější popis fungování těchto souborů je mimo rozsah tohoto článku, pro začátek Vám však značí znát pojmy jako target a task.

MSBuild task je primitivní úkon, který má MSBuild během své práce vykonat. Např. něco zkompilovat, smazat, zkopírovat, založit složku, zkomprimovat do ZIP souboru, transformovat XML, atp. V projektovém souboru se zapisuje jako XML emelent a jeho nastavení se provádí pomocí atributů, viz např. výše uvedený TransformXml task. Základní sada tasků je v MSBuild integrována, další lze připojit jako doplňky (viz výše uvedený Using, který zavádí task TransformXml z .NET assembly).

MSBuild target je něco jako procedura, sada tasků nebo jiných targetů, které se mají vykonat. Pokud např. Visual Studio builduje Váš projekt, volá target „Build“, při publishingu webových aplikací se používají targety jako „CreatePackage“ nebo „TransformWebConfig“. Výchozí konfigurace zahrnuje speciální template-targety „BeforeBuild“, „AfterBuild“ a podobné, kam se snadno můžete zapojit se svými tasky při běžných buildech.

No a to co my ve skutečnosti při výše uvedených transformacích XML souborů děláme, je ve skutečnosti to, že do targetu AfterBuild přidáme task TransformXml (před tím zavedený pomocí Using), který v patřičné fází buildu transformaci provede.

Jak na editaci projektových souborů z Visual Studia:

  1. Projekt, do jehož projektového souboru budete zasahovat, je zpravidla potřeba „unloadovat“ (jen málokterý projektový soubor lze editovat, pokud je projekt zaveden, např. u .wdproj Web Deployment Projectu to lze). V Solution Exploreru tedy pravým tlačítkem klikneme na projekt a dáme „Unload project“ (unloadovaný project se sbalí a zašedne).
  2. Nyní můžeme v Solution Exploreru pravým tlačítkem na projekt a dát „Edit project file“
  3. V typickém projektovém souboru najdete targety AfterBuild a BeforeBuild jako připravené zakomentované XML elementy (odkomentujte!), obvykle někde ke konci souboru (na začátku je zpravidla nastavení projektu, uprostřed používané soubory, ke konci buildové věci):
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->

4.  Po potřebných úpravách souboru a jeho uložení stačí opět dát pravým na projekt v Solution Exploreru a „Reload Project“.

5.  Nyní můžete buildovat…

Pokud zapomenete udělat Reload Project, projekt se Vám bude při buildu ignorovat, což nemusí být hned zjevné.

Outlook 2010: Při kliknutí na hyperlink v mailu se zobrazí „This operation has been cancelled due to restrictions in effect on this computer.“

Pachatelem problému je pravděpodobně prohlížeč Chrome (resp. jeho „interakce“ s registry a Outlookem).
Postup řešení je jednoduchý:

  1. Spustit editor registrů (regedit)
  2. Otevřít větev HKEY_CURRENT_USER\Software\Classes\.html
  3. Kliknout pravým tlačítkem na položku .html a zvolit upravit.
  4. Změnit hodnotu z „ChromeHTML“ na „htmlfile“ (nebo z čehokoliv jiného na „htmlfile“)
  5. To samé pro .htm, .shtml a .xhtml

Konfigurace: Microsoft Windows 7 x64, IE8, Microsoft Outlook 2010 x64.

No files were found to look in. Find was stopped in progress. (Hledání v souborech, VS 2008)

Při pokusu o hledání v souborech se mi zobrazuje hláška: No files were found to look in. Find was stopped in progress.
Říkám si hmm, asi bug. Restartuju Visual Studio a bude vyřešeno.
Restart nepomohl.
Chvilku googluju a nacházím návod, který (stejně jako autor článku) zařazuji kategorie „Kdybych to neviděl, tak bych tomu nevěřil.“ Cože? Zmáčknout Ctrl+ScrollLock a začne to fungovat? Skutečně! Neuvěřitelné. Co to je? Jak na to někdo přišel? Smekám…

UPDATE: Ve VS 2010 (x64) mi se stejným problémem právě pomohl stisk samotné klávesy Break/Pause.

XmlDataSource – pozor na jeho cachování při nastavování property Data

XmlDataSource má poměrně předurčený scénář použití a dokáže velmi nemile překvapit, pokud zapojíte vlastní fantazii a v dobré víře ho použijete jinak (ač zdravý člověk by očekával, že to fungovat bude). Tak především:

  • vlastnost EnableCaching je defaultně nastavena na true (což není úplně očekávané, ale budiž, dokumentované),
  • Cache je však poměrně zákeřná a ne vždy reflektuje vaše změny, vše se odvíjí od implementace metod GetXmlDocument() a  CreateCacheKey(), z nichž lze vyčíst, co všechno považuje XmlDataSource za změnu situace vyžadující reload dat a co ne.
  • tak například změna hodnoty property Data (zápis nového XML stringu) změnou pro Cache není a XmlDataSource vesele vrací stále původní XML až do vypršení Cache!
  • za změnu se považuje zejména změna v hodnotě DataFile nebo TransformFile, dále pak změna souboru, na který se DataFile nebo TransformFile odkazují,
  • XmlDataSource je tedy předurčeno pro použití právě přímo s XML soubory uloženými na disku, na které se odkazujete pomocí DataFile a TransformFile, zatímco přímé nastavování property Data je poněkud nedotažený scénář (i když přípustný).

…z čehož se pro mě jen potvrzuje, že datasources (CokolivDataSource) jsou cesta do pekel. :-)