Sdílet prostřednictvím


Profilery CLR a aplikace pro Windows Store

Toto téma popisuje, co je potřeba zvážit při psaní diagnostických nástrojů, které analyzují spravovaný kód spuštěný v aplikaci pro Windows Store. Obsahuje také pokyny pro úpravu stávajících vývojových nástrojů, aby fungovaly i při jejich spuštění v aplikacích pro Windows Store. Abyste pochopili tyto informace, je nejlepší, pokud znáte rozhraní API pro profilaci modulu Common Language Runtime, už jste toto rozhraní API použili v diagnostickém nástroji, který běží správně v desktopových aplikacích Windows a teď vás zajímá, jak nástroj správně spouštět v aplikacích pro Windows Store.

Úvod

Pokud jste ho provedli za úvodní odstavec, pak znáte rozhraní API pro profilaci CLR. Už jste napsali diagnostický nástroj, který dobře funguje u spravovaných desktopových aplikací. Teď vás zajímá, co dělat, aby váš nástroj fungoval se spravovanou aplikací pro Windows Store. Možná jste se už pokusili tuto práci udělat a zjistili jste, že to není jednoduchý úkol. Existuje řadu aspektů, které nemusí být pro všechny vývojáře nástrojů zřejmé. Příklad:

  • Aplikace pro Windows Store běží v kontextu s výrazně omezenými oprávněními.

  • Soubory metadat Systému Windows mají jedinečné vlastnosti v porovnání s tradičními spravovanými moduly.

  • Aplikace pro Windows Store mají zvyk pozastavit se, když dojde k výpadku interaktivity.

  • Vaše mechanismy komunikace mezi procesy už nemusí fungovat z různých důvodů.

Toto téma obsahuje seznam věcí, o které potřebujete vědět a jak se s nimi správně vypořádat.

Pokud s rozhraním CLR Profiling API začínáte, přejděte na konec tohoto tématu a vyhledejte lepší úvodní informace.

Poskytnutí podrobností o konkrétních rozhraních API systému Windows a jejich použití je také mimo rozsah tohoto tématu. Toto téma je výchozím bodem a další informace o všech rozhraních API pro Windows, na která se odkazuje, najdete na webu MSDN.

Architektura a terminologie

Diagnostický nástroj má obvykle architekturu, jako je architektura zobrazená na následujícím obrázku. Používá termín profiler, ale mnoho takových nástrojů přesahuje typický výkon nebo profilaci paměti do oblastí, jako je pokrytí kódu, napodobení rozhraní objektů, ladění časového cestování, monitorování aplikací atd. Pro zjednodušení bude toto téma nadále odkazovat na všechny tyto nástroje jako profilátory.

V tomto tématu se používá následující terminologie:

Aplikace

Toto je aplikace, kterou profiler analyzuje. Vývojář této aplikace teď obvykle používá profiler k diagnostice problémů s aplikací. Tradičně by tato aplikace byla desktopovou aplikací pro Windows, ale v tomto tématu se díváme na aplikace pro Windows Store.

Knihovna DLL profileru

Jedná se o komponentu, která se načte do procesního prostoru analyzované aplikace. Tato komponenta, označovaná také jako profiler "agent", implementuje rozhraní ICorProfilerCallback ICorProfilerCallbackInterface(2,3 atd.) a využívá rozhraní ICorProfilerInfo(2,3 atd.) ke shromažďování dat o analyzované aplikaci a potenciálně ke změně aspektů chování aplikace.

Uživatelské rozhraní profileru

Jedná se o desktopovou aplikaci, se kterou uživatel profileru komunikuje. Zodpovídá za zobrazení stavu aplikace uživateli a poskytnutí prostředků k řízení chování analyzované aplikace. Tato komponenta vždy běží ve vlastním prostoru procesu odděleně od prostoru procesu profilované aplikace. Uživatelské rozhraní Profileru může také fungovat jako trigger připojení, což je proces, který volá ICLRProfiling::AttachProfiler metoda, aby analyzovaná aplikace načetla knihovnu DLL profileru v takových případech, kdy knihovna DLL profileru nebyla načtena při spuštění.

Důležité

Uživatelské rozhraní Profileru by mělo zůstat desktopovou aplikací pro Windows, i když se používá k řízení a vytváření sestav v aplikaci pro Windows Store. Neočekávejte, že budete moct zabalit a odeslat diagnostický nástroj do Windows Storu. Váš nástroj musí dělat věci, které aplikace pro Windows Store nemůžou dělat, a mnoho z těchto věcí se nachází v uživatelském rozhraní Profileru.

V tomto dokumentu vzorový kód předpokládá, že:

  • Knihovna DLL profileru je napsaná v jazyce C++, protože musí být nativní knihovnou DLL podle požadavků rozhraní CLR Profiling API.

  • Vaše uživatelské rozhraní Profileru je napsané v jazyce C#. To není nutné, ale protože pro váš proces uživatelského rozhraní Profileru nejsou žádné požadavky, proč si nevybít jazyk, který je stručný a jednoduchý?

Zařízení s Windows RT

Zařízení s Windows RT jsou docela uzamčená. Na taková zařízení nelze jednoduše načíst profilátory třetích stran. Tento dokument se zaměřuje na počítače s Windows 8.

Využívání rozhraní API prostředí Windows Runtime

V řadě scénářů probíraných v následujících částech musí desktopová aplikace profileru využívat některé nové rozhraní API prostředí Windows Runtime. Budete se chtít podívat do dokumentace, abyste pochopili, která prostředí Windows Runtime rozhraní API se dají používat z desktopových aplikací a jestli se jejich chování liší při zavolání z desktopových aplikací a aplikací pro Windows Store.

Pokud je vaše uživatelské rozhraní Profileru napsané ve spravovaném kódu, budete muset udělat několik kroků, abyste tyto prostředí Windows Runtime rozhraní API usnadnili. Další informace najdete v článku Spravované desktopové aplikace a prostředí Windows Runtime.

Načtení knihovny DLL profileru

Tato část popisuje, jak uživatelské rozhraní profileru způsobí, že aplikace pro Windows Store načte knihovnu DLL profileru. Kód probíraný v této části patří do desktopové aplikace Profiler UI, a proto zahrnuje použití rozhraní API pro Windows, která jsou bezpečná pro desktopové aplikace, ale nemusí být nutně bezpečná pro aplikace pro Windows Store.

Uživatelské rozhraní profileru může způsobit načtení knihovny DLL profileru do prostoru procesu aplikace dvěma způsoby:

  • Při spuštění aplikace se řídí proměnnými prostředí.

  • Připojením k aplikaci po spuštění je dokončen voláníM ICLRProfiling::AttachProfiler metoda.

Jedním z vašich prvních překážek bude načítání při spuštění a připojování načítání knihovny DLL profileru, aby správně fungovaly s aplikacemi pro Windows Store. Obě formy načítání sdílejí některé zvláštní aspekty společné, takže začněme s nimi.

Běžné aspekty při spouštění a připojování zatížení

Podepisování knihovny DLL profileru

Když se Systém Windows pokusí načíst knihovnu DLL profileru, ověří, zda je knihovna DLL profileru správně podepsaná. Pokud ne, zatížení ve výchozím nastavení selže. Toto lze provést dvěma způsoby:

  • Ujistěte se, že je vaše knihovna DLL profileru podepsaná.

  • Před použitím nástroje dejte uživateli vědět, že musí na svém počítači s Windows 8 nainstalovat vývojářskou licenci. Můžete to provést automaticky ze sady Visual Studio nebo ručně z příkazového řádku. Další informace najdete v tématu Získání licence pro vývojáře.

Oprávnění systému souborů

Aplikace pro Windows Store musí mít oprávnění k načtení a spuštění knihovny DLL profileru z umístění v systému souborů, ve kterém se nachází Ve výchozím nastavení, aplikace pro Windows Store nemá takové oprávnění pro většinu adresářů a všechny neúspěšné pokusy o načtení knihovny DLL profileru vytvoří položku v protokolu událostí aplikace systému Windows, která vypadá nějak takto:

NET Runtime version 4.0.30319.17929 - Loading profiler failed during CoCreateInstance.  Profiler CLSID: '{xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'.  HRESULT: 0x80070005.  Process ID (decimal): 4688.  Message ID: [0x2504].

Obecně platí, že aplikace pro Windows Store mají povolený přístup jenom k omezené sadě umístění na disku. Každá aplikace pro Windows Store má přístup ke svým vlastním datovým složkám aplikací a také k několika dalším oblastem v systému souborů, ke kterým mají přístup všechny aplikace pro Windows Store. Nejlepší je nainstalovat knihovnu DLL profileru a její závislosti někde v části Program Files nebo Program Files (x86), protože všechny aplikace pro Windows Store mají ve výchozím nastavení oprávnění ke čtení a spouštění.

Spouštěcí zatížení

V desktopové aplikaci se v uživatelském rozhraní Profileru obvykle zobrazí výzva ke spuštění knihovny DLL profileru tím, že inicializuje blok prostředí, který obsahuje požadované proměnné prostředí ROZHRANÍ API profilace CLR (tj COR_PROFILER. , COR_ENABLE_PROFILINGa COR_PROFILER_PATH) a pak vytvoří nový proces s tímto blokem prostředí. Totéž platí pro aplikace pro Windows Store, ale mechanismy se liší.

Nespouštět zvýšenou úroveň

Pokud se proces A pokusí vytvořit proces aplikace pro Windows Store B, měl by být proces A spuštěn na střední úrovni integrity, ne na vysoké úrovni integrity (to znamená ne se zvýšenými oprávněními). To znamená, že uživatelské rozhraní Profileru by mělo běžet na střední úrovni integrity, nebo musí vytvořit jiný desktopový proces na střední úrovni integrity, aby se postaral o spuštění aplikace pro Windows Store.

Volba aplikace pro Windows Store k profilování

Nejprve se budete chtít zeptat svého uživatele profileru, který aplikaci pro Windows Store má spustit. U desktopových aplikací byste možná zobrazili dialogové okno Procházet soubor a uživatel by našel a vybral .exe soubor. Aplikace pro Windows Store se ale liší a použití dialogového okna Procházet nedává smysl. Místo toho je lepší zobrazit uživateli seznam aplikací pro Windows Store nainstalovaných pro tohoto uživatele, ze kterého si ho vybere.

K PackageManager vygenerování tohoto seznamu můžete použít třídu. PackageManagerje prostředí Windows Runtime třída, která je k dispozici pro desktopové aplikace a ve skutečnosti je dostupná jenom pro desktopové aplikace.

Následující příklad kódu z hypotetického uživatelského rozhraní Profileru napsaného jako desktopová aplikace v jazyce C# používá PackageManager k vygenerování seznamu aplikací pro Windows:

string currentUserSID = WindowsIdentity.GetCurrent().User.ToString();
IAppxFactory appxFactory = (IAppxFactory) new AppxFactory();
PackageManager packageManager = new PackageManager();
IEnumerable<Package> packages = packageManager.FindPackagesForUser(currentUserSID);

Zadání vlastního bloku prostředí

Nové rozhraní MODELU COM, IPackageDebug Nastavení, umožňuje přizpůsobit chování provádění aplikace pro Windows Store, aby se usnadnily některé formy diagnostiky. Jedna z jejích metod , EnableDebugging, umožňuje předat blok prostředí do aplikace pro Windows Store při jeho spuštění spolu s dalšími užitečnými efekty, jako je zakázání automatického pozastavení procesu. Blok prostředí je důležitý, protože tam, kde potřebujete zadat proměnné prostředí (COR_PROFILER, COR_ENABLE_PROFILINGa COR_PROFILER_PATH)) používané CLR k načtení knihovny DLL profileru.

Vezměte v úvahu následující fragment kódu:

IPackageDebugSettings pkgDebugSettings = new PackageDebugSettings();
pkgDebugSettings.EnableDebugging(packageFullName, debuggerCommandLine,
                                                                 (IntPtr)fixedEnvironmentPzz);

Existuje několik položek, které potřebujete získat správně:

  • packageFullName lze určit při iterování přes balíčky a pochytit package.Id.FullName.

  • debuggerCommandLine je trochu zajímavější. Pokud chcete předat vlastní blok prostředí do aplikace pro Windows Store, musíte napsat vlastní, zjednodušený ladicí program. Windows vytvoří pozastavenou aplikaci pro Windows Store a pak připojí ladicí program spuštěním ladicího programu pomocí příkazového řádku, jako je v tomto příkladu:

    MyDummyDebugger.exe -p 1336 -tid 1424
    

    kde -p 1336 znamená, že aplikace pro Windows Store má ID procesu 1336 a -tid 1424 znamená, že vlákno s ID 1424 je vlákno, které je pozastavené. Váš fiktivní ladicí program parsuje THREADID z příkazového řádku, obnoví toto vlákno a pak ukončí.

    Tady je příklad kódu C++, který to provede (nezapomeňte přidat kontrolu chyb!):

    int wmain(int argc, wchar_t* argv[])
    {
        // …
        // Parse command line here
        // …
    
        HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME,
                                                                  FALSE /* bInheritHandle */, nThreadID);
        ResumeThread(hThread);
        CloseHandle(hThread);
        return 0;
    }
    

    Tento fiktivní ladicí program budete muset nasadit jako součást instalace diagnostického nástroje a pak v parametru zadat cestu k tomuto ladicímu debuggerCommandLine programu.

Spuštění aplikace pro Windows Store

V okamžiku, kdy se aplikace pro Windows Store konečně spustila, přišla. Pokud jste to už vyzkoušeli sami, možná jste si všimli, že CreateProcess není způsob vytvoření procesu aplikace pro Windows Store. Místo toho budete muset použít metodu IApplicationActivationManager::ActivateApplication . K tomu budete muset získat ID modelu uživatele aplikace pro aplikaci pro Windows Store, kterou spouštíte. A to znamená, že se budete muset trochu prokopávat manifestem.

Při iterování balíčků (viz "Volba aplikace pro Windows Store k profilování" v části Načítání po spuštění dříve), budete chtít získat sadu aplikací obsažených v manifestu aktuálního balíčku:

string manifestPath = package.InstalledLocation.Path + "\\AppxManifest.xml";

AppxPackaging.IStream manifestStream;
SHCreateStreamOnFileEx(
                    manifestPath,
                    0x00000040,     // STGM_READ | STGM_SHARE_DENY_NONE
                    0,              // file creation attributes
                    false,          // fCreate
                    null,           // reserved
                    out manifestStream);

IAppxManifestReader manifestReader = appxFactory.CreateManifestReader(manifestStream);

IAppxManifestApplicationsEnumerator appsEnum = manifestReader.GetApplications();

Ano, jeden balíček může mít více aplikací a každá aplikace má vlastní ID modelu uživatele aplikace. Proto budete chtít požádat uživatele, kterou aplikaci profilovat, a získat ID modelu uživatele aplikace z této konkrétní aplikace:

while (appsEnum.GetHasCurrent() != 0)
{
    IAppxManifestApplication app = appsEnum.GetCurrent();
    string appUserModelId = app.GetAppUserModelId();
    //...
}

Nakonec máte to, co potřebujete ke spuštění aplikace pro Windows Store:

IApplicationActivationManager appActivationMgr = new ApplicationActivationManager();
appActivationMgr.ActivateApplication(appUserModelId, appArgs, ACTIVATEOPTIONS.AO_NONE, out pid);

Nezapomeňte volat DisableDebugging

Když jste volali IPackageDebug Nastavení::EnableDebugging, jste slíbili, že po sobě zavoláte IPackageDebug Nastavení::D isableDebugging metoda, takže nezapomeňte to udělat, když je relace profilace skončila.

Připojit zatížení

Pokud vaše uživatelské rozhraní Profileru chce připojit jeho profiler DLL k aplikaci, která již byla spuštěna, používá ICLRProfiling::AttachProfiler. Totéž platí i pro aplikace pro Windows Store. Kromě výše uvedených běžných aspektů se ujistěte, že cílová aplikace pro Windows Store není pozastavená.

Povolit ladění

Stejně jako při spouštění volejte metodu IPackageDebug Nastavení::EnableDebugging. K předání bloku prostředí ho nepotřebujete, ale potřebujete některou z dalších funkcí: zákaz automatického pozastavení procesu. Jinak může být cílové aplikace pro Windows Store pozastavená, když vaše uživatelské rozhraní Profileru volá AttachProfiler. Ve skutečnosti je to pravděpodobné, pokud uživatel pracuje s uživatelským rozhraním Profileru a aplikace pro Windows Store není aktivní na žádné z obrazovek uživatele. A pokud je aplikace pro Windows Store pozastavená, nebude moct reagovat na žádný signál, že clr do ní odešle, aby připojil knihovnu DLL profileru.

Proto budete chtít udělat něco takového:

IPackageDebugSettings pkgDebugSettings = new PackageDebugSettings();
pkgDebugSettings.EnableDebugging(packageFullName, null /* debuggerCommandLine */,
                                                                 IntPtr.Zero /* environment */);

Jedná se o stejné volání, které byste udělali pro případ načítání při spuštění, s výjimkou toho, že nezadáte příkazový řádek ladicího programu nebo blok prostředí.

Zakázat ladění

Jako vždy nezapomeňte volat IPackageDebug Nastavení::D isableDebugging při dokončení relace profilace.

Spuštění v aplikaci pro Windows Store

Aplikace pro Windows Store tedy konečně načetla knihovnu DLL profileru. Teď musí být knihovna DLL profileru naučit, jak přehrávat různá pravidla vyžadovaná aplikacemi pro Windows Store, včetně toho, která rozhraní API jsou povolená a jak se s nižšími oprávněními spustit.

Přichytejte se k rozhraním API aplikací pro Windows Store.

Při procházení rozhraní API pro Windows si všimnete, že každé rozhraní API je zdokumentované jako použitelné pro desktopové aplikace, aplikace pro Windows Store nebo obojí. Například část Požadavky v dokumentaci pro funkci InitializeCriticalSectionAndSpinCount indikuje, že tato funkce se vztahuje pouze na desktopové aplikace. Naproti tomu funkce InitializeCriticalSectionEx je k dispozici pro desktopové aplikace i aplikace pro Windows Store.

Při vývoji knihovny DLL profileru s ní zachází, jako by se jedná o aplikaci pro Windows Store a používala pouze rozhraní API, která jsou zdokumentovaná jako dostupná pro aplikace pro Windows Store. Analyzujte závislosti (například můžete spustit link /dump /imports proti knihovně DLL profileru a auditovat) a pak v dokumentaci vyhledejte, které závislosti jsou v pořádku a které nejsou. Ve většině případů je možné porušení opravit tak, že je jednoduše nahradíte novější formou rozhraní API, které je zdokumentované jako bezpečné (například nahrazením InitializeCriticalSectionAndSpinCount inicializeCriticalSectionEx).

Možná si všimnete, že vaše knihovna DLL profileru volá některá rozhraní API, která se vztahují pouze na desktopové aplikace, a přesto se zdá, že fungují i v případě, že je knihovna DLL profileru načtena do aplikace pro Windows Store. Mějte na paměti, že je rizikové používat jakékoli rozhraní API, které není zdokumentované pro použití s aplikacemi pro Windows Store v knihovně DLL profileru při načtení do procesu aplikace pro Windows Store:

  • Taková rozhraní API nejsou zaručená, že při zavolání v jedinečném kontextu, ve které běží aplikace pro Windows Store.

  • Taková rozhraní API nemusí fungovat konzistentně při zavolání z různých procesů aplikací pro Windows Store.

  • Tato rozhraní API můžou vypadat dobře z aplikací pro Windows Store v aktuální verzi Windows, ale v budoucích verzích Windows se můžou přerušit nebo zakázat.

Nejlepší doporučení je opravit všechna porušení a vyhnout se riziku.

Možná zjistíte, že bez konkrétního rozhraní API nemůžete dělat a nemůžete najít náhradu vhodnou pro aplikace pro Windows Store. V takovém případě minimálně:

  • Otestujte, otestujte, otestujte živé denní světlo z vašeho využití tohoto rozhraní API.

  • Mějte na vědomí, že rozhraní API se může náhle přerušit nebo zmizet, pokud se volá z aplikací pro Windows Store v budoucích verzích Windows. Microsoft to nepovažuje za problém s kompatibilitou a podpora vašeho využití nebude prioritou.

Omezená oprávnění

Seznam všech způsobů, jak se oprávnění aplikací pro Windows Store liší od desktopových aplikací, je mimo rozsah tohoto tématu. Ale určitě se chování bude lišit pokaždé, když se vaše knihovna PROFILER DLL (při načtení do aplikace pro Windows Store ve srovnání s desktopovou aplikací) pokusí získat přístup k jakýmkoli prostředkům. Nejběžnějším příkladem je systém souborů. Na disku je ale několik míst, ke kterým má daná aplikace pro Windows Store povolený přístup (viz Přístup k souborům a oprávnění (prostředí Windows Runtime aplikace) a knihovna DLL profileru bude mít stejná omezení. Důkladně otestujte kód.

Komunikace mezi procesy

Jak je znázorněno v diagramu na začátku tohoto dokumentu, bude knihovna DLL profileru (načtená do prostoru procesu aplikace pro Windows Store) pravděpodobně muset komunikovat s uživatelským rozhraním profileru (spuštěným v samostatném prostoru procesu desktopové aplikace) prostřednictvím vlastního kanálu komunikace mezi procesy (IPC). Uživatelské rozhraní Profileru odesílá signály do knihovny DLL profileru, aby změnilo jeho chování, a knihovna DLL profileru odesílá data z analyzované aplikace pro Windows Store zpět do uživatelského rozhraní profileru pro následné zpracování a zobrazení uživateli profileru.

Většina profilátorů musí pracovat tímto způsobem, ale vaše volby pro mechanismy IPC jsou omezenější, když se knihovna DLL profileru načte do aplikace pro Windows Store. Pojmenované kanály například nejsou součástí sady SDK aplikace pro Windows Store, takže je nemůžete použít.

Ale samozřejmě, soubory jsou stále v, i když omezenější způsobem. K dispozici jsou také události.

Komunikace prostřednictvím souborů

Většina vašich dat bude pravděpodobně předávat mezi profiler DLL a profiler UI prostřednictvím souborů. Klíčem je vybrat umístění souboru, ke kterému má knihovna DLL profileru (v kontextu aplikace pro Windows Store) i uživatelské rozhraní Profileru přístup ke čtení a zápisu. Cesta k dočasné složce je například umístění, ke kterému má přístup jak vaše uživatelské rozhraní Profiler DLL, tak k uživatelskému rozhraní Profiler Profiler, ale k žádnému jinému balíčku aplikace pro Windows Store nemá přístup (tedy stínění jakýchkoli informací, které protokolujete z jiných balíčků aplikací pro Windows Store).

Tuto cestu lze nezávisle určit jak v uživatelském rozhraní profileru, tak knihovnu DLL profileru. Uživatelské rozhraní Profileru, když iteruje všechny balíčky nainstalované pro aktuálního uživatele (viz vzorový kód dříve), získá přístup ke PackageId třídě, ze které může být cesta k dočasné složce odvozena pomocí kódu podobného tomuto fragmentu kódu. (Stejně jako vždy je kontrola chyb vynechána kvůli stručnosti.)

// C# code for the Profiler UI.
ApplicationData appData =
    ApplicationDataManager.CreateForPackageFamily(
        packageId.FamilyName);

tempDir = appData.TemporaryFolder.Path;

Mezitím může vaše knihovna DLL profileru provádět v podstatě stejnou věc, i když se může snadněji dostat ke ApplicationData třídě pomocí ApplicationData.Current vlastnost.

Komunikace prostřednictvím událostí

Pokud chcete jednoduchou sémantiku signalizace mezi uživatelským rozhraním Profileru a knihovnou DLL profileru, můžete použít události v aplikacích pro Windows Store i desktopové aplikace.

Z knihovny DLL profileru můžete jednoduše volat funkci CreateEventEx a vytvořit pojmenovanou událost s libovolným názvem. Příklad:

// Profiler DLL in Windows Store app (C++).
CreateEventEx(
    NULL,  // Not inherited
    "MyNamedEvent"
    CREATE_EVENT_MANUAL_RESET, /* explicit ResetEvent() required; leave initial state unsignaled */
    EVENT_ALL_ACCESS);

Uživatelské rozhraní profileru pak musí tuto pojmenovanou událost najít v oboru názvů aplikace pro Windows Store. Uživatelské rozhraní profileru může například volat CreateEventEx a zadat název události jako

AppContainerNamedObjects\<acSid>\MyNamedEvent

<acSid> je SID appContainer pro Windows Store. Předchozí část tohoto tématu ukázala, jak iterovat balíčky nainstalované pro aktuálního uživatele. Z ukázkového kódu můžete získat id balíčku. A z packageId můžete získat <acSid> kód podobný následujícímu:

IntPtr acPSID;
DeriveAppContainerSidFromAppContainerName(packageId.FamilyName, out acPSID);

string acSid;
ConvertSidToStringSid(acPSID, out acSid);

string acDir;
GetAppContainerFolderPath(acSid, out acDir);

Žádná oznámení o vypnutí

Při spuštění v aplikaci pro Windows Store by se vaše knihovna DLL profileru neměla spoléhat na volání ICorProfilerCallback::Shutdown nebo dokonce DllMain (s DLL_PROCESS_DETACH) upozorňovat knihovnu DLL profileru na ukončení aplikace pro Windows Store. Ve skutečnosti byste měli očekávat, že se nikdy nebudou volat. V minulosti mnoho knihoven DLL profileru tato oznámení používala jako praktická místa pro vyprázdnění mezipaměti na disk, zavření souborů, odesílání oznámení zpět do uživatelského rozhraní profileru atd. Teď ale vaše knihovna DLL profileru musí být uspořádaná trochu jinak.

Knihovna DLL profileru by měla být informace o protokolování. Z důvodů výkonu můžete chtít dávkové informace v paměti vyprázdnit a vyprázdnit ji na disk, protože dávka roste o velikost za určitou prahovou hodnotu. Předpokládejme ale, že všechny informace, které ještě nejsou vyprázdněné na disk, mohou být ztraceny. To znamená, že budete chtít vybrat prahovou hodnotu moudře a že uživatelské rozhraní Profileru musí být posíleno, aby bylo možné řešit neúplné informace napsané knihovnou DLL profileru.

prostředí Windows Runtime soubory metadat

Je mimo rozsah tohoto dokumentu a podrobně se dozvíte, co jsou soubory prostředí Windows Runtime metadat (WinMD). Tato část je omezená na to, jak rozhraní CLR Profiling API reaguje, když jsou soubory WinMD načteny aplikací pro Windows Store, kterou vaše knihovna Profiler DLL analyzuje.

Spravované a nespravované winMD

Pokud vývojář pomocí sady Visual Studio vytvoří nový projekt komponenty prostředí Windows Runtime, vytvoří sestavení tohoto projektu soubor WinMD, který popisuje metadata (popisy typů tříd, rozhraní atd.), které vytvořil vývojář. Pokud se jedná o projekt spravovaného jazyka napsaný v jazyce C# nebo Visual Basic, obsahuje stejný soubor WinMD také implementaci těchto typů (to znamená, že obsahuje všechny IL zkompilované ze zdrojového kódu vývojáře). Tyto soubory se označují jako spravované soubory WinMD. Jsou zajímavé v tom, že obsahují metadata prostředí Windows Runtime i základní implementaci.

Pokud vývojář vytvoří projekt komponenty prostředí Windows Runtime pro jazyk C++, vytvoří sestavení tohoto projektu soubor WinMD, který obsahuje pouze metadata, a implementace se zkompiluje do samostatné nativní knihovny DLL. Podobně soubory WinMD, které jsou dodávány v sadě Windows SDK, obsahují pouze metadata s implementací zkompilovanou do samostatných nativních knihoven DLL, které se dodávají jako součást Windows.

Níže uvedené informace platí pro spravované winMD, které obsahují metadata a implementaci, a pro nespravované winMD, které obsahují pouze metadata.

Soubory WinMD vypadají jako moduly CLR

Pokud jde o CLR, všechny soubory WinMD jsou moduly. Rozhraní CLR Profiling API proto říká knihovně PROFILER DLL, když se soubory WinMD načtou a jaké jsou jejich ID modulů, stejným způsobem jako u jiných spravovaných modulů.

Knihovna DLL profileru dokáže odlišit soubory WinMD od jiných modulů zavoláním metody ICorProfilerInfo3::GetModuleInfo2 a kontrolou výstupního pdwModuleFlags parametru příznaku COR_PRF_MODULE_WINDOWS_RUNTIME . (Je nastavena, pokud a pouze pokud ModuleID představuje WinMD.)

Čtení metadat z winMD

Soubory WinMD, jako jsou běžné moduly, obsahují metadata, která je možné číst prostřednictvím rozhraní API metadat. CLR ale mapuje prostředí Windows Runtime typy na typy rozhraní .NET Framework, když čte soubory WinMD, aby vývojáři, kteří programují ve spravovaném kódu a využívají soubor WinMD, mohli mít přirozenější programovací prostředí. Příklady těchto mapování najdete v tématu Podpora rozhraní .NET Framework pro aplikace pro Windows Store a prostředí Windows Runtime.

Které zobrazení se vašemu profileru zobrazí, když používá rozhraní API metadat: nezpracované zobrazení prostředí Windows Runtime nebo mapované zobrazení rozhraní .NET Framework? Odpověď: je na vás.

Při volání ICorProfilerInfo::GetModuleMetaData metoda v WinMD získat rozhraní metadat, jako je IMetaDataImport, můžete nastavit ParametrNoTransform v dwOpenFlags parametru vypnout toto mapování. V opačném případě se ve výchozím nastavení povolí mapování. Profiler obvykle zachová mapování povolené, takže řetězce, které knihovna DLL profileru získá z metadat WinMD (například názvy typů), budou pro uživatele profileru dobře známé a přirozené.

Úprava metadat z winMD

Úpravy metadat ve WinMD nejsou podporovány. Pokud zavoláte metodu ICorProfilerInfo::GetModuleMetaData pro soubor WinMD a zadáteWritev parametru dwOpenFlags nebo požádáte o zapisovatelné rozhraní metadat, jako je IMetaDataEmit, GetModuleMetaData selže. To je obzvláště důležité pro profilátory il-reriting, které potřebují upravit metadata tak, aby podporovaly jejich instrumentaci (například pro přidání AssemblyRefs nebo nových metod). Proto byste měli nejprve zkontrolovat COR_PRF_MODULE_WINDOWS_RUNTIME (jak je popsáno v předchozí části) a nepožadovat na tyto moduly rozhraní pro zapisovatelná metadata.

Překlad odkazů na sestavení pomocí WinMD

Mnoho profilátorů musí vyřešit odkazy na metadata ručně, aby pomohly s instrumentací nebo kontrolou typů. Tito profilátoři musí vědět, jak CLR překládá odkazy na sestavení odkazující na WinMD, protože tyto odkazy jsou vyřešeny zcela jiným způsobem než standardní odkazy na sestavení.

Profilátory paměti

Uvolňování paměti a spravovaná halda se v aplikaci pro Windows Store a desktopové aplikaci zásadně neliší. Existuje však několik drobných rozdílů, o nichž musí autoři profileru vědět.

ForceGC vytvoří spravované vlákno.

Při profilaci paměti vaše knihovna DLL Profiler obvykle vytvoří samostatné vlákno, od kterého se má volat ForceGC Method metoda . Tohle není nic nového. Co ale může být překvapením, je, že provedení uvolňování paměti uvnitř aplikace pro Windows Store může vaše vlákno transformovat na spravované vlákno (například pro toto vlákno se vytvoří ID vlákna rozhraní API pro profilaci).

Abyste pochopili důsledky tohoto postupu, je důležité pochopit rozdíly mezi synchronními a asynchronními voláními definovanými rozhraním API pro profilaci CLR. Všimněte si, že se to velmi liší od konceptu asynchronních volání v aplikacích pro Windows Store. Další informace najdete v blogovém příspěvku Proč máme CORPROF_E_UNSUPPORTED_CALL_SEQUENCE .

Relevantním bodem je, že volání vláken vytvořená vaším profilerem jsou vždy považována za synchronní, i když jsou tato volání provedena mimo implementaci jedné z metod ICorProfilerCallback knihovny Profiler DLL. Aspoň, že to byl případ. Teď, když CLR změnil vlákno profileru na spravované vlákno kvůli volání ForceGC Method, toto vlákno už není považováno za vlákno profileru. CLR proto vynucuje přísnější definici toho, co se kvalifikuje jako synchronní pro dané vlákno – konkrétně to, že volání musí pocházet z jedné z metod ICorProfilerCallback vaší knihovny Profiler, aby bylo kvalifikovat jako synchronní.

Co to znamená v praxi? Většina ICorProfilerInfo metody jsou bezpečné pouze pro synchronní zavolání a okamžitě selže jinak. Pokud tedy knihovna DLL profileru opakovaně používá vlákno ForceGC Method pro jiná volání obvykle vytvořená ve vláknech vytvořených profilerem (například pro RequestProfilerDetach, RequestReJIT nebo RequestRevert), budete mít potíže. Dokonce i asynchronní-bezpečná funkce, jako je DoStackSnapshot , má speciální pravidla při zavolání ze spravovaných vláken. (Viz blogový příspěvek Profiler stack walking: Základy a další informace.)

Proto doporučujeme, aby jakékoli vlákno, které vaše knihovna DLL Profiler vytvoří pro volání ForceGC Metoda , měla být použita pouze pro účely aktivace GCS a následné reakce na zpětná volání GC. Neměl by volat rozhraní API pro profilaci k provádění dalších úloh, jako je vzorkování zásobníku nebo odpojení.

ConditionalWeakTableReferences

Počínaje rozhraním .NET Framework 4.5 existuje nová zpětná vazba GC ConditionalWeakTableElementReferences, která poskytuje profileru podrobnější informace o závislých popisovačích. Tyto obslužné rutiny efektivně přidávají odkaz ze zdrojového objektu do cílového objektu pro účely správy životnosti GC. Závislé popisovače nejsou nic nového a vývojáři, kteří programují ve spravovaném kódu, byli schopni vytvořit vlastní závislé popisovače pomocí System.Runtime.CompilerServices.ConditionalWeakTable<TKey,TValue> třídy i před Windows 8 a .NET Framework 4.5.

Spravované aplikace XAML pro Windows Store teď ale výrazně využívají závislé popisovače. ClR je používá zejména ke správě referenčních cyklů mezi spravovanými objekty a nespravovanými prostředí Windows Runtime objekty. To znamená, že je teď důležitější než kdy dřív, aby profilátory paměti byly informovány o těchto závislých popisovačích, aby je bylo možné vizualizovat spolu se zbytkem okrajů v grafu haldy. Knihovna DLL profileru by měla společně používat RootReferences2, ObjectReferences a ConditionalWeakTableElementReferences a vytvořit kompletní zobrazení grafu haldy.

Závěr

Rozhraní CLR Profiling API je možné použít k analýze spravovaného kódu spuštěného v aplikacích pro Windows Store. Ve skutečnosti můžete použít existující profiler, který vyvíjíte, a provádět určité změny, aby mohl cílit na aplikace pro Windows Store. Uživatelské rozhraní Profileru by mělo používat nová rozhraní API pro aktivaci aplikace pro Windows Store v režimu ladění. Ujistěte se, že knihovna DLL profileru využívá pouze tato rozhraní API použitelná pro aplikace pro Windows Store. Komunikační mechanismus mezi knihovnou DLL profileru a uživatelským rozhraním profileru by měl být napsán s ohledem na omezení rozhraní API aplikací pro Windows Store a s povědomím o omezených oprávněních pro aplikace pro Windows Store. Knihovna DLL profileru by měla vědět, jak CLR zpracovává WinMD a jak se chování uvolňování paměti liší vzhledem ke spravovaným vlákenm.

Zdroje informací

The Common Language Runtime

Interakce CLR s prostředí Windows Runtime

Aplikace pro Windows Store