Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Application.cs / 1305600 / Application.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // The Application object is a global object that the Avalon platform // uses to identify, reference, and communicate with an Avalon application. // // The application object also presents a consistent logical view of an application // to an Avalon developer. // An Avalon developer uses the application object to listen and respond to application-wide // events (like startup, shutdown, and navigation events), // to define global properties and maintain state across multiple pages of markup. // // History: // 04/25/01: sramani Created // 04/27/01: rogerg Added stub for creating the default form. // 05/06/03: marka Moved over to WCP dir. Made match spec, updated comments. // 07/11/03: lgolding Removed code for UseDefaultApp and ContainerNoCode. // 08/12/03: [....] Changed ShutDown to Shutdown (bug 856983) // 08/10/04: kusumav Moved NavigationApplication and other navigation classes to separate files in Navigation dir. // 02/04/05: hamidm Made certain Application APIs thread safe // 06/16/05: weibz Remove RegisterDefaultResourceManager // 01/31/06: brucemac Change PreloadedPackages.AddPackage() to pass a boolean indicating that ResourceContainer is thread-safe // //--------------------------------------------------------------------------- //In order to avoid generating warnings about unknown message numbers and unknown pragmas //when compiling your C# source code with the actual C# compiler, you need to disable //warnings 1634 and 1691. (From PreSharp Documentation) #pragma warning disable 1634, 1691 using System.Collections; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.Remoting; using System.Runtime.Remoting.Lifetime; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Resources; using System.Threading; using System.IO.Packaging; using System.Windows.Threading; using System.Windows.Navigation; using System.Windows; using System.Windows.Interop; using System.Windows.Resources; using System.Windows.Markup; using System.Net; using System.Text; using MS.Internal; using MS.Internal.AppModel; using MS.Internal.IO.Packaging; using MS.Internal.Interop; using MS.Internal.Navigation; using MS.Internal.Utility; using MS.Internal.Resources; using MS.Utility; using MS.Win32; using Microsoft.Win32; using System.Collections.Generic; namespace System.Windows { ////// Delegate for Startup Event /// public delegate void StartupEventHandler(Object sender, StartupEventArgs e); ////// Delegate for the Exit event. /// public delegate void ExitEventHandler(Object sender, ExitEventArgs e); ////// Delegate for SessionEnding event /// public delegate void SessionEndingCancelEventHandler(Object sender, SessionEndingCancelEventArgs e); #region Application Class ////// Application base class /// public class Application : DispatcherObject, IHaveResources, IQueryAmbient { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// The static constructor calls ApplicationInit /// static Application() { ApplicationInit(); } ////// Application constructor /// ////// Critical: This code posts a work item to start dispatcher if in the browser /// PublicOk: It is ok because the call itself is not exposed and the application object does this internally. /// [SecurityCritical] public Application() { #if DEBUG_CLR_MEM if (CLRProfilerControl.ProcessIsUnderCLRProfiler && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { CLRProfilerControl.CLRLogWriteLine("Application_Ctor"); } #endif // DEBUG_CLR_MEM EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordGeneral | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientAppCtor); lock(_globalLock) { // set the default statics // DO NOT move this from the begining of this constructor if (_appCreatedInThisAppDomain == false) { Debug.Assert(_appInstance == null, "_appInstance must be null here."); _appInstance = this; IsShuttingDown = false; _appCreatedInThisAppDomain = true; } else { //lock will be released, so no worries about throwing an exception inside the lock throw new InvalidOperationException(SR.Get(SRID.MultiSingleton)); } } // NOTE: [....] 12/19/05 // WOSB 1398365 // Post a work item to start the Dispatcher (if we are browser hosted) so that the Dispatcher // will be running before OnStartup is fired. We can't check to see if we are browser-hosted // in the app ctor because BrowerInteropHelper.IsBrowserHosted hasn't been set yet. Dispatcher.BeginInvoke( DispatcherPriority.Send, new DispatcherOperationCallback(StartDispatcherInBrowser), null); // // NOTE: hamidm 08/06/04 // PS Windows OS Bug # 994269 (Application not shutting down when calling // Application.Current.Shutdown()) // // post item to do startup work // posting it here so that this is the first item in the queue. Devs // could post items before calling run and then those will be serviced // before if we don't post this one here. // // Also, doing startup (firing OnStartup etc.) once our dispatcher // is run ensures that we run before any external code is run in the // application's Dispatcher. Dispatcher.BeginInvoke( DispatcherPriority.Send, (DispatcherOperationCallback) delegate(object unused) { // Shutdown may be started before the Dispatcher gets to this callback. // This can happen in browser-hosted applications. if (IsShuttingDown) return null; // Event handler exception continuality: if exception occurs in Startup event handler, // our state would not be corrupted because it is fired by posting the item in the queue. // Please check Event handler exception continuality if the logic changes. StartupEventArgs e = new StartupEventArgs(); OnStartup(e); // PerformDefaultAction is used to cancel the default navigation for the case // when the app is being loaded as a result of a history navigation. In such // a case, we don't want to show the startupUri page, rather we show the last // page of the app that we in use before navigating away from it. if (e.PerformDefaultAction) { DoStartup(); } return null; }, null); } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Run is called to start an application. /// /// Typically a developer will do some setting of properties/attaching to events after instantiating an application object, /// and then call Run() to start the application. /// ////// Once run has been called - an application's OnStartup override and Startup event is called /// immediately afterwards. /// ///ExitCode of the application public int Run() { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordGeneral | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientAppRun); return this.Run(null); } ////// Run is called to start an application. /// /// Typically a developer will do some setting of properties/attaching to events after instantiating an application object, /// and then call Run() to start the application. /// Any arguments passed in as a string array will be added to the command Line property of the StartupEventArgs property. /// The exit code returned by Run will typically be returned to the OS as a return value. /// ////// Once run has been called - an application's OnStartup override and Startup event is called /// immediately afterwards. /// /// Window that will be added to the Windows property and made the MainWindow of the Applcation. /// The passed Window must be created on the same thread as the Application object. Furthermore, this Window is /// shown once the Application is run. ///ExitCode of the application ////// Critical: This code calls into RunInternal which is deemed as critical /// PublicOk: This code fails if called in a browser hosted scenario because of the check for InBrowserHosted /// [SecurityCritical] public int Run(Window window) { VerifyAccess(); // // Browser hosted app should not explictly call App.Run(). We need to filter out those // calls here // if (InBrowserHostedApp()) { throw new InvalidOperationException(SR.Get(SRID.CannotCallRunFromBrowserHostedApp)); } else { return RunInternal(window); } } ////// This will return true IFF this is a browser hosted, and this is the user's deployed /// application, not our deployment application. We can't use BrowserCallbackServices for /// this test, because it may not be hooked up yet. BrowserInteropHelper.IsBrowserHosted /// is set before any of the code in the new AppDomain will be run yet. /// internal static bool InBrowserHostedApp() { return BrowserInteropHelper.IsBrowserHosted && !(Application.Current is XappLauncherApp); } ////// /// /// ///internal object GetService(Type serviceType) { // this is called only from OleCmdHelper and it gets // service for IBrowserCallbackServices which is internal. // This call is made on the App thread. // VerifyAccess(); object service = null; if (ServiceProvider != null) { service = ServiceProvider.GetService(serviceType); } return service; } /// /// Shutdown is called to programmatically shutdown an application. /// /// Once shutdown() is called, the application gets called with the /// OnShutdown method to raise the Shutdown event. /// Requires SecurityPermission for unmanaged code /// ////// Requires UIPermission with AllWindows access /// public void Shutdown() { Shutdown(0); } ////// Shutdown is called to programmatically shutdown an application. /// /// Once shutdown() is called, the application gets called with the /// OnShutdown method to raise the Shutdown event. /// The exitCode parameter passed in at Shutdown will be returned as a /// return parameter on the run() method, so it can be passed back to the OS. /// ////// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// /// returned to the Application.Run() method. Typically this will be returned to the OS ////// PublicOK: Demand UIPermission with AllWindows access /// Critical: Calls critical code ShutDownDelegate /// [SecurityCritical] public void Shutdown(int exitCode) { SecurityHelper.DemandUIWindowPermission(); CriticalShutdown(exitCode); } ////// Critical: This code calls into shut down code which is critical. /// [SecurityCritical] internal void CriticalShutdown(int exitCode) { VerifyAccess(); //Already called once?? if (IsShuttingDown == true) { return; } SetExitCode(exitCode); IsShuttingDown = true; Dispatcher.BeginInvoke(DispatcherPriority.Normal, new DispatcherOperationCallback(ShutdownCallback), null); } ////// Searches for a resource with the passed resourceKey and returns it /// ////// If the sources is not found on the App, SystemResources are searched. /// /// Name of the resource ///The found resource. ///if the key is not found. public object FindResource(object resourceKey) { ResourceDictionary resources = _resources; object resource = null; if (resources != null) { resource = resources[resourceKey]; } if (resource == DependencyProperty.UnsetValue || resource == null) { // This is the top of the tree, try the system resource collection // Safe from multithreading issues, SystemResources uses the SyncRoot lock to access the resource resource = SystemResources.FindResourceInternal(resourceKey); } if (resource == null) { Helper.ResourceFailureThrow(resourceKey); } return resource; } ////// Searches for a resource with the passed resourceKey and returns it /// ////// If the sources is not found on the App, SystemResources are searched. /// /// Name of the resource ///The found resource. Null if not found. public object TryFindResource(object resourceKey) { ResourceDictionary resources = _resources; object resource = null; if (resources != null) { resource = resources[resourceKey]; } if (resource == DependencyProperty.UnsetValue || resource == null) { // This is the top of the tree, try the system resource collection // Safe from multithreading issues, SystemResources uses the SyncRoot lock to access the resource resource = SystemResources.FindResourceInternal(resourceKey); } return resource; } // // Internal routine only look up in application resources // internal object FindResourceInternal(object resourceKey) { // Call Forwarded return FindResourceInternal(resourceKey, false /*allowDeferredResourceReference*/, false /*mustReturnDeferredResourceReference*/); } internal object FindResourceInternal(object resourceKey, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference) { ResourceDictionary resources = _resources; if (resources == null) { return null; } else { bool canCache; return resources.FetchResource(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache); } } ////// Create logic tree from given resource Locator, and associate this /// tree with the given component. /// /// Root Element /// Resource Locator ////// Critical: This code calls critical method GetResourceOrContentStream to get part. /// PublicOK: The part is not exposed. /// [SecurityCritical] public static void LoadComponent(Object component, Uri resourceLocator) { if (component == null) throw new ArgumentNullException("component"); if (resourceLocator == null) throw new ArgumentNullException("resourceLocator"); if (resourceLocator.OriginalString == null) throw new ArgumentException(SR.Get(SRID.ArgumentPropertyMustNotBeNull,"resourceLocator", "OriginalString")); if (resourceLocator.IsAbsoluteUri == true) throw new ArgumentException(SR.Get(SRID.AbsoluteUriNotAllowed)); // Passed a relative Uri here. // needs to resolve it to Pack://Application. //..\..\ in the relative Uri will get stripped when creating the new Uri and resolving to the //PackAppBaseUri, i.e. only relative Uri within the appbase are created here Uri currentUri = new Uri(BaseUriHelper.PackAppBaseUri, resourceLocator); // // Generate the ParserContext from packUri // ParserContext pc = new ParserContext(); pc.BaseUri = currentUri; bool bCloseStream = true; // Whether or not to close the stream after LoadBaml is done. Stream stream = null; // stream could be extracted from the manifest resource or cached in the // LoadBamlSyncInfo depends on how this method is called. // // We could be here because of an InitializeCompoenent() call from the ctor of this component. // Check if this component was originally being created from the same Uri by the BamlConverter // or LoadComponent(uri). // if (IsComponentBeingLoadedFromOuterLoadBaml(currentUri) == true) { NestedBamlLoadInfo nestedBamlLoadInfo = s_NestedBamlLoadInfo.Peek(); // If so, use the stream already created for this component on this thread by the // BamlConverter and seek to origin. This gives better perf by avoiding a duplicate // WebRequest. stream = nestedBamlLoadInfo.BamlStream; stream.Seek(0, SeekOrigin.Begin); pc.SkipJournaledProperties = nestedBamlLoadInfo.SkipJournaledProperties; // Reset the OuterUri in the top LoadBamlSyncInfo in the stack for the performance optimization. nestedBamlLoadInfo.BamlUri = null; // Start a new load context for this component to allow it to initialize normally via // its InitializeComponent() so that code in the ctor following it can access the content. // This call will not close the stream since it is owned by the load context created by // the BamlConverter and will be closed from that context after this function returns. bCloseStream = false; } else { // if not, this is a first time regular load of the component. PackagePart part = GetResourceOrContentPart(resourceLocator); ContentType contentType = new ContentType(part.ContentType); stream = part.GetStream(); bCloseStream = true; // // The stream must be a BAML stream. // check the content type. // if (!MimeTypeMapper.BamlMime.AreTypeAndSubTypeEqual(contentType)) { throw new Exception(SR.Get(SRID.ContentTypeNotSupported, contentType)); } } IStreamInfo bamlStream = stream as IStreamInfo; if (bamlStream == null || bamlStream.Assembly != component.GetType().Assembly) { throw new Exception(SR.Get(SRID.UriNotMatchWithRootType, component.GetType( ), resourceLocator)); } XamlReader.LoadBaml(stream, pc, component, bCloseStream); } ////// Create logic tree from given resource Locator, and return the root of /// this tree. /// /// Resource Locator public static object LoadComponent(Uri resourceLocator) { if (resourceLocator == null) throw new ArgumentNullException("resourceLocator"); if (resourceLocator.OriginalString == null) throw new ArgumentException(SR.Get(SRID.ArgumentPropertyMustNotBeNull,"resourceLocator", "OriginalString")); if (resourceLocator.IsAbsoluteUri == true) throw new ArgumentException(SR.Get(SRID.AbsoluteUriNotAllowed)); return LoadComponent(resourceLocator, false); } //// Create logic tree from given resource Locator, and return the root of // this tree. // // Resource Locator // SkipJournaledProperties or not ////// Critical - calls critical method GetResourceOrContentPart /// TreatAsSafe: /// Part is not exposed. /// /// This internal method is called only by the public LoadComponent(uri) and /// the journal navigation for PageFunction when the PageFunction was navigated /// from a markup file or is implemented from a xaml file. /// /// [SecurityCritical, SecurityTreatAsSafe] internal static object LoadComponent(Uri resourceLocator, bool bSkipJournaledProperties) { // // Only the Public LoadComponent(uri) and Journal navigation for PageFunction resume // call this method, the caller should have ensure the passed paramaters are valid. // So don't need to explicitly do the validation check for the parameters. // // Passed a relative Uri here. // needs to resolve it to Pack://Application. //..\..\ in the relative Uri will get stripped when creating the new Uri and resolving to the //PackAppBaseUri, i.e. only relative Uri within the appbase are created here Uri packUri = BindUriHelper.GetResolvedUri(BaseUriHelper.PackAppBaseUri, resourceLocator); PackagePart part = GetResourceOrContentPart(packUri); ContentType contentType = new ContentType(part.ContentType); Stream stream = part.GetStream(); ParserContext pc = new ParserContext(); pc.BaseUri = packUri; pc.SkipJournaledProperties = bSkipJournaledProperties; // // The stream must be a BAML or XAML stream. // if (MimeTypeMapper.BamlMime.AreTypeAndSubTypeEqual(contentType)) { return LoadBamlStreamWithSyncInfo(stream, pc); } else if (MimeTypeMapper.XamlMime.AreTypeAndSubTypeEqual(contentType)) { return XamlReader.Load(stream, pc); } else { throw new Exception(SR.Get(SRID.ContentTypeNotSupported, contentType.ToString())); } } // // A helper method to create a tree from a baml stream. // // This helper will be called by BamlConverter and LoadComponent(Uri). // // If root element type in the bamlstream was compiled from a xaml file, // and the bamlstream created from the xaml file is exact same as the baml stream // passed in this method, we don't want to generate duplicate tree nodes. // Navigate(Uri) and LoadComponent(Uri) may hit this situation. // // The caller should prepare baml stream and appropriate ParserContext. // internal static object LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc) { object rootElement = null; // The callers should have already done the parameter validation. // So the code here uses assert instead of throwing exception. // Debug.Assert(stream != null, "stream should not be null."); Debug.Assert(pc != null, "pc should not be null."); try { if (s_NestedBamlLoadInfo == null) { s_NestedBamlLoadInfo = new Stack(); } // Keep the Uri and Stream which is being handled by LoadBaml in this thread. // If the ctor of the root element in this tree calls the InitializeComponent // method, the baml loaded in that context will go through and this one will // be skipped to completion automatically, since the same stream will be used, // essentially making the LoadBaml in this helper a No-OP. // NestedBamlLoadInfo loadBamlSyncInfo = new NestedBamlLoadInfo(pc.BaseUri, stream, pc.SkipJournaledProperties); s_NestedBamlLoadInfo.Push(loadBamlSyncInfo); // LoadBaml will close the stream. rootElement = XamlReader.LoadBaml(stream, pc, null, true); } finally { // Reset the per-thread Uri & Stream setting to indicate that tree generation // from the baml stream is done. s_NestedBamlLoadInfo.Pop(); if (s_NestedBamlLoadInfo.Count == 0) { s_NestedBamlLoadInfo = null; } } return rootElement; } /// /// Get PackagePart for a uri, the uri maps to a resource which is embedded /// inside manifest resource "$(AssemblyName).g.resources" in Application or /// dependent library assembly. /// /// If the Uri doesn't map to any resource, this method returns null. /// /// The accepted uri could be relative uri or pack uri. /// /// Such as /// Resource from Application assembly /// "image/picture1.jpg" or /// "pack://application:,,,/image/picture1.jpg" /// /// Resource from a library assembly /// "mylibrary;component/image/picture2.png" or /// "pack://application:,,,/mylibrary;component/image/picture3.jpg" /// /// /// the uri maps to the resource ///PackagePart or null ////// Critical: This code calls critical method GetResourceOrContentStream to get part. /// PublicOK: The part is not exposed. /// [SecurityCritical] public static StreamResourceInfo GetResourceStream(Uri uriResource) { if (uriResource == null) throw new ArgumentNullException("uriResource"); if (uriResource.OriginalString == null) throw new ArgumentException(SR.Get(SRID.ArgumentPropertyMustNotBeNull, "uriResource", "OriginalString")); if (uriResource.IsAbsoluteUri == true && !BaseUriHelper.IsPackApplicationUri(uriResource)) { throw new ArgumentException(SR.Get(SRID.NonPackAppAbsoluteUriNotAllowed)); } ResourcePart part = GetResourceOrContentPart(uriResource) as ResourcePart; return (part == null) ? null : new StreamResourceInfo(part.GetStream(), part.ContentType); } ////// Get PackagePart for a uri, the uri maps to a content file which is associated /// with the application assembly. /// /// If the Uri doesn't map to any content file, this method returns null. /// /// The accepted uri could be relative uri or pack://Application:,,,/ uri. /// /// Such as /// "image/picture1.jpg" /// or /// "pack://application:,,,/image/picture1.jpg" /// /// /// the uri maps to the Content File ///PackagePart or null ////// Critical: This code calls critical method GetResourceOrContentStream to get part. /// PublicOK: The part is not exposed. /// [SecurityCritical] public static StreamResourceInfo GetContentStream(Uri uriContent) { if (uriContent == null) throw new ArgumentNullException("uriContent"); if (uriContent.OriginalString == null) throw new ArgumentException(SR.Get(SRID.ArgumentPropertyMustNotBeNull, "uriContent", "OriginalString")); if (uriContent.IsAbsoluteUri == true && !BaseUriHelper.IsPackApplicationUri(uriContent)) { throw new ArgumentException(SR.Get(SRID.NonPackAppAbsoluteUriNotAllowed)); } ContentFilePart part = GetResourceOrContentPart(uriContent) as ContentFilePart; return (part == null) ? null : new StreamResourceInfo(part.GetStream(), part.ContentType); } ////// Get PackagePart for a uri, the uri maps to a file which comes from the place /// where the application was originally deployed. /// /// The accepted uri could be relative uri such as "foo.jpg" /// /// or pack Uri, "pack://siteoforigin:,,,/foo.jpg" /// /// /// the uri maps to the resource ///PackagePart or null ////// Critical: Calls the Critical GetResourcePackage(). /// PublicOK: The package is not exposed. /// [SecurityCritical] public static StreamResourceInfo GetRemoteStream(Uri uriRemote) { SiteOfOriginPart sooPart = null; if (uriRemote == null) throw new ArgumentNullException("uriRemote"); if (uriRemote.OriginalString == null) throw new ArgumentException(SR.Get(SRID.ArgumentPropertyMustNotBeNull, "uriRemote", "OriginalString")); if (uriRemote.IsAbsoluteUri == true) { if (BaseUriHelper.SiteOfOriginBaseUri.IsBaseOf(uriRemote) != true) { throw new ArgumentException(SR.Get(SRID.NonPackSooAbsoluteUriNotAllowed)); } } Uri resolvedUri = BindUriHelper.GetResolvedUri(BaseUriHelper.SiteOfOriginBaseUri, uriRemote); // Using PackUriHelper.ValidateAndGetPackUriComponents internal method // to get Package and Part Uri in one step Uri packageUri; Uri partUri; PackUriHelper.ValidateAndGetPackUriComponents(resolvedUri, out packageUri, out partUri); // // SiteOfOriginContainer must have been added into the package cache, the code should just // take use of that SiteOfOriginContainer instance, instead of creating a new instance here. // SiteOfOriginContainer sooContainer = (SiteOfOriginContainer)GetResourcePackage(packageUri); sooPart = sooContainer.GetPart(partUri) as SiteOfOriginPart; // // Verify if the sooPart is for a valid remote file. // Stream stream = null; if (sooPart != null) { try { stream = sooPart.GetStream(); if (stream == null) { // // Cannot get stream from this PackagePart for some unknown reason, // since the code didn't throw WebException. // sooPart = null; } } catch (WebException) { // A WebException is thrown when the code tried to get stream from the PackagePart. // The Uri passed to this method must be a wrong uri. // Return null for this case. sooPart = null; // For all other exceptions such as security exception, etc, let it go to upper frame, // and fail eventually if no exception handler wants to catch it. } } // When stream is not null, sooPart cannot be null either Debug.Assert( ((stream != null) && (sooPart == null)) != true, "When stream is not null, sooPart cannot be null either"); return (stream == null) ? null : new StreamResourceInfo(stream, sooPart.ContentType); } ////// Gets the cookie for the uri. It will work only for site of origin. /// /// The uri for which the cookie is to be read ///The cookie, if it exsits, else an exception is thrown. ////// Callers must have FileIOPermission(FileIOPermissionAccess.Read) or WebPermission(NetworkAccess.Connect) for the Uri, depending on whether the Uri is a file Uri or not, to call this API. /// public static string GetCookie(Uri uri) { return CookieHandler.GetCookie(uri, true/*throwIfNoCookie*/); } ////// Sets the cookie for the uri. It will work only for site of origin. /// /// The uri for which the cookie is to be set /// The value of the cookie. Should be name=value, but "value-only" cookies are also allowed. ////// Callers must have FileIOPermission(FileIOPermissionAccess.Read) or WebPermission(NetworkAccess.Connect) for the Uri, depending on whether the Uri is a file Uri or not, to call this API. /// public static void SetCookie(Uri uri, string value) { CookieHandler.SetCookie(uri, value); } #endregion Public Methods //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region Public Properties ////// The Current property enables the developer to always get to the application in /// AppDomain in which they are running. /// static public Application Current { get { // There is no need to take the _globalLock because reading a // reference is an atomic operation. Moreover taking a lock // also causes risk of re-entrancy because it pumps messages. return _appInstance; } } ////// The Windows property exposes a WindowCollection object, from which a developer /// can iterate over all the windows that have been opened in the current application. /// // DO-NOT USE THIS PROPERY IF YOU MEAN TO MODIFY THE UNDERLYING COLLECTION. USE // WindowsInternal PROPERTY FOR MODIFYING THE UNDERLYING DATASTRUCTURE. public WindowCollection Windows { get { VerifyAccess(); return WindowsInternal.Clone(); } } ////// The MainWindow property indicates the primary window of the application. /// Note that setting the mainWindow property is not possible for browser hosted applications. /// ////// By default - MainWindow will be set to the first window opened in the application. /// However the MainWindow may be set programmatically to indicate "this is my main window". /// It is a recommended programming style to refer to MainWindow in code instead of Windows[0]. /// /// public Window MainWindow { get { VerifyAccess(); return _mainWindow; } set { VerifyAccess(); // // Throw if an attempt is made to change RBW. // or we are browser hosted, main window is null, and attempt is made to change RBW. // if ( ( _mainWindow is RootBrowserWindow ) || ((BrowserCallbackServices != null ) && ( _mainWindow == null ) && ( !( value is RootBrowserWindow ))) ) { throw new InvalidOperationException( SR.Get( SRID.CannotChangeMainWindowInBrowser ) ) ; } if (value != _mainWindow) { _mainWindow = value; } } } ////// The ShutdownMode property is called to set the shutdown specific mode of /// the application. Setting this property controls the way in which an application /// will shutdown. /// The three values for the ShutdownMode enum are : /// OnLastWindowClose /// OnMainWindowClose /// OnExplicitShutdown /// /// OnLastWindowClose - this mode will shutdown the application when the /// last window is closed, or an explicit call is made /// to Application.Shutdown(). This is the default mode. /// /// OnMainWindowClose - this mode will shutdown the application when the main /// window has been closed, or Application.Shutdown() is /// called. Note that if the MainWindow property has not /// been set - this mode is equivalent to OnExplicitOnly. /// /// OnExplicitShutdown- this mode will shutdown the application only when an /// explicit call to OnShutdown() has been made. /// public ShutdownMode ShutdownMode { get { VerifyAccess(); return _shutdownMode; } set { VerifyAccess(); if ( !IsValidShutdownMode(value) ) { throw new InvalidEnumArgumentException("value", (int)value, typeof(ShutdownMode)); } if (IsShuttingDown == true || _appIsShutdown == true) { throw new InvalidOperationException(SR.Get(SRID.ShutdownModeWhenAppShutdown)); } _shutdownMode = value; } } ////// Current locally defined Resources /// [Ambient] public ResourceDictionary Resources { //Don't use VerifyAccess() here since Resources can be set from any thread. //We synchronize access using _globalLock get { ResourceDictionary resources; bool needToAddOwner = false; lock(_globalLock) { if (_resources == null) { // Shouldn't return null for property of type collection. // It enables the Mort scenario: application.Resources.Add(); _resources = new ResourceDictionary(); needToAddOwner = true; } resources = _resources; } if (needToAddOwner) { resources.AddOwner(this); } return resources; } set { bool invalidateResources = false; ResourceDictionary oldValue; lock(_globalLock) { oldValue = _resources; _resources = value; } if (oldValue != null) { // This app is no longer an owner for the old RD oldValue.RemoveOwner(this); } if (value != null) { if (!value.ContainsOwner(this)) { // This app is an owner for the new RD value.AddOwner(this); } } if (oldValue != value) { invalidateResources = true; } if (invalidateResources) { InvalidateResourceReferences(new ResourcesChangeInfo(oldValue, value)); } } } ResourceDictionary IHaveResources.Resources { get { return Resources; } set { Resources = value; } } bool IQueryAmbient.IsAmbientPropertyAvailable(string propertyName) { // We want to make sure that StaticResource resolution checks the .Resources // Ie. The Ambient search should look at Resources if it is set. // Even if it wasn't set from XAML (eg. the Ctor (or derived Ctor) added stuff) return (propertyName == "Resources" && _resources != null); } // Says if App.Resources has any implicit styles internal bool HasImplicitStylesInResources { get { return _hasImplicitStylesInResources; } set { _hasImplicitStylesInResources = value; } } ////// The main page /// ////// This property should only be called from the Application thread /// public Uri StartupUri { get { VerifyAccess(); return _startupUri; } set { VerifyAccess(); if (value == null) { throw new ArgumentNullException("value"); } _startupUri = value; } } ////// Gets the property Hashtable. /// ///IDictionary interface ////// This property is accessible from any thread /// public IDictionary Properties { get { // change from before; Before we used to return null // but that might throw a nullpointer exception if // indexers are being used on the Hashtable object lock(_globalLock) { if (_htProps == null) { // so we will have 5 entries before we resize _htProps = new HybridDictionary(5); } return _htProps; } } } ////// This property gets and sets the assembly pack://application:,,,/ refers to. /// public static Assembly ResourceAssembly { get { if (_resourceAssembly == null) { lock (_globalLock) { _resourceAssembly = Assembly.GetEntryAssembly(); } } return _resourceAssembly; } set { lock (_globalLock) { if (_resourceAssembly != value) { if ((_resourceAssembly == null) && (Assembly.GetEntryAssembly() == null)) { _resourceAssembly = value; BaseUriHelper.ResourceAssembly = value; } else { throw new InvalidOperationException(SR.Get(SRID.PropertyIsImmutable, "ResourceAssembly", "Application")); } } } } } #endregion Public Properties //----------------------------------------------------- // // Public Events // //------------------------------------------------------ #region Public Events ////// The Startup event is fired when an application is starting. /// This event is raised by the OnStartup method. /// public event StartupEventHandler Startup { add{ VerifyAccess(); Events.AddHandler(EVENT_STARTUP, value); } remove{ VerifyAccess(); Events.RemoveHandler(EVENT_STARTUP, value); } } ////// The Exit event is fired when an application is shutting down. /// This event is raised by the OnExit method. /// public event ExitEventHandler Exit { add{ VerifyAccess(); Events.AddHandler(EVENT_EXIT, value); } remove{ VerifyAccess(); Events.RemoveHandler(EVENT_EXIT, value); } } ////// The Activated event is fired when an applications window has been activated from /// the OS ( alt-tab, or changing application from taskbar, or clicking on a winodw). /// This event is raised by the OnActivated method. /// public event EventHandler Activated; ////// The Deactivated event is fired when an applications window has been de-activated /// from the OS ( alt-tab, or changing application from taskbar, or clicking away /// from an applications window). This event is raised by the OnDeactivated method. /// public event EventHandler Deactivated; ////// The SessionEnding event is fired when windows is ending, either due to a shutdown, /// or loggoff from the start menu ( or calling the ExitWindows function). The /// ReasonSessionEnding enum on the SessionEndingEventArgs indicates whether the session /// is ending in response to a shutdown of the OS, or if the user is logging off. /// ////// By setting cancel to true on the SessionEndingCancelEventArgs, the app can prevent /// the user from logging off. Hence attempting to cancel this is a high trust /// operation and this is enforced when the event is handled. No listener can cancel /// this event if the app is partial trust. /// public event SessionEndingCancelEventHandler SessionEnding { add{ VerifyAccess(); Events.AddHandler(EVENT_SESSIONENDING, value); } remove{ VerifyAccess(); Events.RemoveHandler(EVENT_SESSIONENDING, value); } } ////// The DispatcherUnhandledException event is fired when an unhandled exception /// is caught at the Dispatcher level (by the dispatcher). /// public event DispatcherUnhandledExceptionEventHandler DispatcherUnhandledException { //Dispatcher.Invoke will call the callback on the dispatcher thread so a VerifyAccess() //check is redundant (and wrong) outside the invoke call add { Dispatcher.Invoke( DispatcherPriority.Send, (DispatcherOperationCallback) delegate(object unused) { Dispatcher.UnhandledException += value; return null; }, null); } remove { Dispatcher.Invoke( DispatcherPriority.Send, (DispatcherOperationCallback) delegate(object unused) { Dispatcher.UnhandledException -= value; return null; }, null); } } ////// public event NavigatingCancelEventHandler Navigating; ////// public event NavigatedEventHandler Navigated; ////// public event NavigationProgressEventHandler NavigationProgress; ////// This event is fired when an error is encountered during a navigation /// public event NavigationFailedEventHandler NavigationFailed; ////// public event LoadCompletedEventHandler LoadCompleted; ////// public event NavigationStoppedEventHandler NavigationStopped; ////// public event FragmentNavigationEventHandler FragmentNavigation; #endregion Public Events //----------------------------------------------------- // // Protected Methods // //----------------------------------------------------- #region Protected Methods ////// OnStartup is called to raise the Startup event. The developer will typically override this method /// if they want to take action at startup time ( or they may choose to attach an event). /// This method will be called once when the application begins, once that application's Run() method /// has been called. /// ////// This method follows the .Net programming guideline of having a protected virtual method /// that raises an event, to provide a convenience for developers that subclass the event. /// If you override this method - you need to call Base.OnStartup(...) for the corresponding event /// to be raised. /// /// The event args that will be passed to the Startup event protected virtual void OnStartup(StartupEventArgs e) { VerifyAccess(); StartupEventHandler handler = (StartupEventHandler)Events[EVENT_STARTUP]; if (handler != null) { handler(this, e); } } ////// OnExit is called to raise the Exit event. /// The developer will typically override this method if they want to take /// action when the application exits ( or they may choose to attach an event). /// ////// This method follows the .Net programming guideline of having a protected virtual method /// that raises an event, to provide a convenience for developers that subclass the event. /// If you override this method - you need to call Base.OnExit(...) for the /// corresponding event to be raised. /// /// The event args that will be passed to the Exit event protected virtual void OnExit(ExitEventArgs e) { VerifyAccess(); ExitEventHandler handler = (ExitEventHandler)Events[EVENT_EXIT]; if (handler != null) { handler(this, e); } } ////// OnActivated is called to raise the Activated event. /// The developer will typically override this method if they want to take action /// when the application gets activated ( or they may choose to attach an event). /// This method will be called when one of the current applications windows gets /// activated on the desktop. ( This corresponds to Users WM_ACTIVATEAPP message). /// ////// This method follows the .Net programming guideline of having a protected /// virtual method that raises an event, to provide a convenience for developers /// that subclass the event. /// /// protected virtual void OnActivated(EventArgs e) { VerifyAccess(); if (Activated != null) { Activated(this, e); } } ////// OnDeactivated is called to raise the Deactivated event. The developer will /// typically override this method if they want to take action when the application /// gets deactivated ( or they may choose to attach an event). /// This method will be called when one of the current applications windows gets /// activated on the desktop. ( This corresponds to Users WM_ACTIVATEAPP message, /// with an wparam indicating the app is being deactivated). /// ////// This method follows the .Net programming guideline of having a protected virtual /// method that raises an event, to provide a convenience for developers that /// subclass the event. /// /// protected virtual void OnDeactivated(EventArgs e) { VerifyAccess(); if (Deactivated != null) { Deactivated(this, e); } } ////// OnSessionEnding is called to raise the SessionEnding event. The developer will /// typically override this method if they want to take action when the OS is ending /// a session ( or they may choose to attach an event). This method will be called when /// the user has chosen to either logoff or shutdown. These events are equivalent /// to receiving a WM_QUERYSESSION window event. Windows will send it when user is /// logging out/shutting down. ( See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/wm_queryendsession.asp ). /// By default if this event is not cancelled - Avalon will then call Application.Shutdown. /// ////// This method follows the .Net programming guideline of having a protected virtual /// method that raises an event, to provide a convenience for developers that subclass /// the event. /// /// protected virtual void OnSessionEnding(SessionEndingCancelEventArgs e) { VerifyAccess(); SessionEndingCancelEventHandler handler = (SessionEndingCancelEventHandler)Events[EVENT_SESSIONENDING]; if (handler != null) { handler(this, e); } } ////// This method fires the Navigating event /// ////// This method follows the .Net programming guideline of having a protected virtual /// method that raises an event, to provide a convenience for developers that subclass /// the event. If you override this method - you need to call Base.OnNavigating(...) for /// the corresponding event to be raised. /// /// NavigationEventArgs protected virtual void OnNavigating(NavigatingCancelEventArgs e) { VerifyAccess(); if (Navigating != null) { Navigating(this, e); } } ////// This method fires the Navigated event /// on receiving all of the stream contents /// for the given bpu /// ////// This method follows the .Net programming guideline of having a protected virtual /// method that raises an event, to provide a convenience for developers that subclass /// the event. If you override this method - you need to call Base.OnNavigated(...) for /// the corresponding event to be raised. /// /// NavigationEventArgs protected virtual void OnNavigated(NavigationEventArgs e) { VerifyAccess(); if (Navigated != null) { Navigated(this, e); } } ////// This method fires the NavigationProgress event /// each time number of bytes equal to bytesInterval is read /// ////// This method follows the .Net programming guideline of having a protected virtual /// method that raises an event, to provide a convenience for developers that subclass /// the event. If you override this method - you need to call Base.OnNavigationProgress(...) for /// the corresponding event to be raised. /// /// NavigationEventArgs protected virtual void OnNavigationProgress(NavigationProgressEventArgs e) { VerifyAccess(); if (NavigationProgress != null) { NavigationProgress(this, e); } } ////// This method fires the NavigationFailed event /// When there is an error encountered in navigation /// ////// This method follows the .Net programming guideline of having a protected virtual /// method that raises an event, to provide a convenience for developers that subclass /// the event. If you override this method - you need to call Base.OnNavigationProgress(...) for /// the corresponding event to be raised. /// /// NavigationFailedEventArgs protected virtual void OnNavigationFailed(NavigationFailedEventArgs e) { VerifyAccess(); if (NavigationFailed != null) { NavigationFailed(this, e); } } ////// This method fires the LoadCompleted event /// after parsing all of the top level page /// and its secondary contents /// ////// This method follows the .Net programming guideline of having a protected virtual /// method that raises an event, to provide a convenience for developers that subclass /// the event. If you override this method - you need to call Base.OnLoadCompleted(...) for /// the corresponding event to be raised. /// /// NavigationEventArgs protected virtual void OnLoadCompleted(NavigationEventArgs e) { VerifyAccess(); if (LoadCompleted != null) { LoadCompleted(this, e); } } ////// This method fires the Stopped event /// whenever the top level has navigated and /// there occurs a stop after that /// ////// This method follows the .Net programming guideline of having a protected virtual /// method that raises an event, to provide a convenience for developers that subclass /// the event. If you override this method - you need to call Base.OnNavigationStopped(...) for /// the corresponding event to be raised. /// /// NavigationEventArgs protected virtual void OnNavigationStopped(NavigationEventArgs e) { VerifyAccess(); if (NavigationStopped != null) { NavigationStopped(this, e); } } ////// This method fires the FragmentNavigation event /// whenever a navigation to a uri containing a fragment /// occurs. /// ////// This method follows the .Net programming guideline of having a protected virtual /// method that raises an event, to provide a convenience for developers that subclass /// the event. If you override this method - you need to call Base.OnNavigationStopped(...) for /// the corresponding event to be raised. /// /// FragmentNavigationEventArgs protected virtual void OnFragmentNavigation(FragmentNavigationEventArgs e) { VerifyAccess(); if (FragmentNavigation != null) { FragmentNavigation(this, e); } } #endregion Protected Methods //----------------------------------------------------- // // Internal Methods // //------------------------------------------------------ #region Internal Methods // It would be nice to make this FamANDAssem (protected and internal) if c# supported it internal virtual void PerformNavigationStateChangeTasks( bool isNavigationInitiator, bool playNavigatingSound, NavigationStateChange state) { if (isNavigationInitiator) { switch (state) { case NavigationStateChange.Navigating: ChangeBrowserDownloadState(true); if (playNavigatingSound) { PlaySound(SOUND_NAVIGATING); } break; case NavigationStateChange.Completed: PlaySound(SOUND_COMPLETE_NAVIGATION); ChangeBrowserDownloadState(false); UpdateBrowserCommands(); break; case NavigationStateChange.Stopped: ChangeBrowserDownloadState(false); break; } } } ////// Critical: Calls IBrowserCallbackServices.UpdateCommands which is critical because it has a SUC /// TreatAsSafe: Calling this method is safe because it merely asks IE to synchronize data with us. /// [SecurityCritical, SecurityTreatAsSafe] internal void UpdateBrowserCommands() { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordHosting | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Verbose, EventTrace.Event.WpfHost_UpdateBrowserCommandsStart); IBrowserCallbackServices ibcs = (IBrowserCallbackServices)this.GetService(typeof(IBrowserCallbackServices)); if (ibcs != null) { // ask the browser to re-query us for toolbar button state ibcs.UpdateCommands(); } EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordHosting | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Verbose, EventTrace.Event.WpfHost_UpdateBrowserCommandsEnd); } ////// Application Startup. /// internal void DoStartup() { Debug.Assert(CheckAccess(), "This should only be called on the Application thread"); if (StartupUri != null) { if (StartupUri.IsAbsoluteUri == false) { // Resolve it against the ApplicationMarkupBaseUri. StartupUri = new Uri(ApplicationMarkupBaseUri, StartupUri); } // ArrowHead Optimization for StartupUri: // When loading app resources (pack://application, we do not need to go through the navigation logic. // We can load the stream through ResourceContainer directly. This way we avoid loading the navigation // and webrequest code. It is also [....], instead of async if going through navigation code pass. // This optimization saves about 3-4% cold startup time for a simple application. // However, we need to maintain back compact in the following areas until we can do breaking change. // 1. Continue to support other uri and content types (the else statement). // 2. Continue to fire Navigating events. if (BaseUriHelper.IsPackApplicationUri(StartupUri)) { // BACK COMPAT: // We need to fire Navigating event to be back compact with V1. // We should drop this when we can do breaking change. Uri relativeUri = BindUriHelper.GetUriRelativeToPackAppBase(StartupUri); NavigatingCancelEventArgs e = new NavigatingCancelEventArgs(relativeUri, null, null, null, NavigationMode.New, null, null, true); FireNavigating(e, true); // Navigating can be cancelled. if (! e.Cancel) { object root = LoadComponent(StartupUri, false); // If the root element is not a window, we need to create a window. ConfigAppWindowAndRootElement(root, StartupUri); } } else { // BACK COMPAT: // The following logic is for pack://siteoforign uri syntax and all other uri and content types // that the WPF navigation framework supports, including Html. // // We want to maintain the V1 behavior to continue support loading those content. I suggest reconsidering // this support when we can do breaking change. We need to understand what scenarios require // the Application StartupUri to load content other than xaml/baml in the app resource or content file. // If there are no interesting ones, we should remove this support. NavService = new NavigationService(null); NavService.AllowWindowNavigation = true; NavService.PreBPReady += new BPReadyEventHandler(OnPreBPReady); NavService.Navigate(StartupUri); } } } ////// DO NOT USE - internal method /// ////// Critical: Calls critical code: Window.InternalClose /// Critical: Calls critical code: HwndSource.Dispose /// Critical: Calls critical code: PreloadedPackages.Clear() /// [SecurityCritical] internal virtual void DoShutdown() { Debug.Assert(CheckAccess() == true, "DoShutdown can only be called on the Dispatcer thread"); // // We use a while loop like this because closing a window will modify the windows list. while(WindowsInternal.Count > 0) { if (!WindowsInternal[0].IsDisposed) { WindowsInternal[0].InternalClose(true, true); } else { WindowsInternal.RemoveAt(0); } } WindowsInternal = null; ExitEventArgs e = new ExitEventArgs(_exitCode); // Event handler exception continuality: if exception occurs in ShuttingDown event handler, // our cleanup action is to finish Shuttingdown. Since Shuttingdown cannot be cancelled. // We don't want user to use throw exception and catch it to cancel Shuttingdown. try { // fire Applicaiton Exit event OnExit(e); } finally { SetExitCode(e._exitCode); // By default statics are shared across appdomains, so need to clear lock (_globalLock) { _appInstance = null; } _mainWindow = null; _htProps = null; NonAppWindowsInternal = null; // this will always be null in the browser hosted case since we we don't // support Activate, Deactivate, and SessionEnding events in the // browser scenario and thus we never create this hwndsource. if (_parkingHwnd != null) { _parkingHwnd.Dispose(); } if (_events != null) { _events.Dispose(); } PreloadedPackages.Clear(); AppSecurityManager.ClearSecurityManager(); _appIsShutdown = true; // mark app as shutdown } } // // This function is called from the public Run methods to start the application. // ApplicationProxyInternal.Run method calls this method directly to bypass the check // for browser hosted application in the public Run() method // ////// Critical: This code calls into Dispatcher.Run which is deemed as critical /// [SecurityCritical] internal int RunInternal(Window window) { VerifyAccess(); #if DEBUG_CLR_MEM if (CLRProfilerControl.ProcessIsUnderCLRProfiler && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { CLRProfilerControl.CLRLogWriteLine("Application_Run"); } #endif // DEBUG_CLR_MEM EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordGeneral | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientAppRun); // // NOTE: hamidm 08/06/04 // PS Windows OS Bug # 901085 (Can't create app and do run/shutdown followed // by run/shutdown) // // Devs could write the following code // // Application app = new Application(); // app.Run(); // app.Run(); // // In this case, we should throw an exception when Run is called for the second time. // When app is shutdown, _appIsShutdown is set to true. If it is true here, then we // throw an exception if (_appIsShutdown == true) { throw new InvalidOperationException(SR.Get(SRID.CannotCallRunMultipleTimes, this.GetType().FullName)); } if (window != null) { if (window.CheckAccess() == false) { throw new ArgumentException(SR.Get(SRID.WindowPassedShouldBeOnApplicationThread, window.GetType().FullName, this.GetType().FullName)); } if (WindowsInternal.HasItem(window) == false) { WindowsInternal.Add(window); } if (MainWindow == null) { MainWindow = window; } if (window.Visibility != Visibility.Visible) { Dispatcher.BeginInvoke( DispatcherPriority.Send, (DispatcherOperationCallback) delegate(object obj) { Window win = obj as Window; win.Show(); return null; }, window); } } EnsureHwndSource(); //Even if the subclass app cancels the event we still want to create and run the dispatcher //so that when the app explicitly calls Shutdown, we have a dispatcher to service the posted //Shutdown DispatcherOperationCallback // Invoke the Dispatcher synchronously if we are not in the browser if (!BrowserInteropHelper.IsBrowserHosted) { RunDispatcher(null); } return _exitCode; } internal void InvalidateResourceReferences(ResourcesChangeInfo info) { // Invalidate ResourceReference properties on all the windows. // we Clone() the collection b/c if we don't then some other thread can be // modifying the collection while we iterate over it InvalidateResourceReferenceOnWindowCollection(WindowsInternal.Clone(), info); InvalidateResourceReferenceOnWindowCollection(NonAppWindowsInternal.Clone(), info); } // Creates and returns a NavigationWindow for standalone cases // For browser hosted cases, returns the existing RootBrowserWindow which // is created before the application.Run is called. ////// Critical: This code returns the rootbrowserwindow which is critical /// [SecurityCritical] internal NavigationWindow GetAppWindow() { NavigationWindow appWin = null; IBrowserCallbackServices ibcs = (IBrowserCallbackServices)this.GetService(typeof(IBrowserCallbackServices)); // standalone case if (ibcs == null) { appWin = new NavigationWindow(); // We don't want to show the window before the content is ready, but for compatibility reasons // we do want it to have an HWND available. Not doing this can cause Application's MainWindow // to be null when LoadCompleted has happened. new WindowInteropHelper(appWin).EnsureHandle(); } else // browser hosted case { IHostService ihs = (IHostService)this.GetService(typeof(IHostService)); Debug.Assert(ihs != null, "IHostService in RootBrowserWindow cannot be null"); appWin = ihs.RootBrowserWindowProxy.RootBrowserWindow; Debug.Assert(appWin != null, "appWin must be non-null"); Debug.Assert(appWin is RootBrowserWindow, "appWin must be a RootBrowserWindow"); } return appWin; } internal void FireNavigating(NavigatingCancelEventArgs e, bool isInitialNavigation) { PerformNavigationStateChangeTasks(e.IsNavigationInitiator, !isInitialNavigation, NavigationStateChange.Navigating); OnNavigating(e); } internal void FireNavigated(NavigationEventArgs e) { OnNavigated(e); } internal void FireNavigationProgress(NavigationProgressEventArgs e) { OnNavigationProgress(e); } internal void FireNavigationFailed(NavigationFailedEventArgs e) { // TFS Dev10 451993 - Browser downloading state not reset; case 1. PerformNavigationStateChangeTasks(true, false, NavigationStateChange.Stopped); OnNavigationFailed(e); } internal void FireLoadCompleted(NavigationEventArgs e) { PerformNavigationStateChangeTasks(e.IsNavigationInitiator, false, NavigationStateChange.Completed); OnLoadCompleted(e); } internal void FireNavigationStopped(NavigationEventArgs e) { PerformNavigationStateChangeTasks(e.IsNavigationInitiator, false, NavigationStateChange.Stopped); OnNavigationStopped(e); } internal void FireFragmentNavigation(FragmentNavigationEventArgs e) { OnFragmentNavigation(e); } #endregion Internal methods //----------------------------------------------------- // // Internal Properties // //------------------------------------------------------ #region Internal Properties // The public Windows property returns a copy of the underlying // WindowCollection. This property is used internally to enable // modyfying the underlying collection. internal WindowCollection WindowsInternal { get { lock(_globalLock) { if(_appWindowList == null) { _appWindowList = new WindowCollection(); } return _appWindowList; } } private set { lock(_globalLock) { _appWindowList = value; } } } internal WindowCollection NonAppWindowsInternal { get { lock(_globalLock) { if (_nonAppWindowList == null) { _nonAppWindowList = new WindowCollection(); } return _nonAppWindowList; } } private set { lock(_globalLock) { _nonAppWindowList = value; } } } //This property indicates what type of an application was created. We use this //to determine whether to update the address bar or not for toplevel navigations //Since we don't currently have support to represent a proper relative uri //for .xps or .deploy or browser hosted exes, we limit address bar //updates to xaml navigations. // internal MimeType MimeType { get { return _appMimeType.Value; } [SecurityCritical] set { _appMimeType = new SecurityCriticalDataForSet(value); } } // this is called from ApplicationProxyInternal, ProgressBarAppHelper, and ContainerActivationHelper. // All of these are on the app thread internal IServiceProvider ServiceProvider { private get { VerifyAccess(); if (_serviceProvider != null) { return _serviceProvider; } else { return null; } } set { VerifyAccess(); _serviceProvider = value ; if (value != null) { _browserCallbackServices = (IBrowserCallbackServices)(_serviceProvider.GetService(typeof(IBrowserCallbackServices))); ILease lease = RemotingServices.GetLifetimeService(_browserCallbackServices as MarshalByRefObject) as ILease; if (lease != null) { //Per the remoting infrastructure, any remote object will get released in 5 mins unless the lease //is extended with the lease manager by a sponsor _browserCallbackSponsor = new SponsorHelper(lease, new TimeSpan(0, 5, 0)); _browserCallbackSponsor.Register(); } } else { CleanUpBrowserCallBackServices(); } } } private void CleanUpBrowserCallBackServices() { if (_browserCallbackServices != null) { if (_browserCallbackSponsor != null) { _browserCallbackSponsor.Unregister(); _browserCallbackSponsor = null; } _browserCallbackServices = null; // Marshal.ReleaseComObject(IBHS) is called from ApplicationProxyInternal. } } internal IBrowserCallbackServices BrowserCallbackServices { get { VerifyAccess(); return _browserCallbackServices; } } // is called by NavigationService to detect TopLevel container // We check there to call this only if NavigationService is on // the same thread as the Application internal NavigationService NavService { get { VerifyAccess(); return _navService; } set { VerifyAccess(); _navService = value; } } /// /// Critical - calls IsShuttingDown which is SUC'ed. /// TreatAsSafe - The knowledge that we're shutting down is not critical. /// internal static bool IsShuttingDown { [SecurityCritical, SecurityTreatAsSafe] get { //If we are shutting down normally, Application.IsShuttingDown will be true. Be sure to check this first. // If we are browser hosted, BrowserCallbackServices.IsShuttingDown checks to see if the browser is shutting us down, // even if we may not be shutting down the Application yet. Check this to avoid reentrance issues between the time that // browser is shutting us down and that Application.Shutdown (CriticalShutdown) is invoked. if (_isShuttingDown) { return _isShuttingDown; } if (BrowserInteropHelper.IsBrowserHosted) { Application app = Application.Current; if ((app != null) && (app.CheckAccess())) { IBrowserCallbackServices bcs = app.BrowserCallbackServices; return ((bcs != null) && bcs.IsShuttingDown()); } } return false; } set { lock(_globalLock) { _isShuttingDown = value; } } } // This returns the static variable _isShuttingDown. internal static bool IsApplicationObjectShuttingDown { get { return _isShuttingDown; } } ////// Returns the handle of the parking window. /// ////// Critical because we expose _parkingHwnd, which is critical. /// internal IntPtr ParkingHwnd { [SecurityCritical] get { if (_parkingHwnd != null) { return _parkingHwnd.Handle; } else { return IntPtr.Zero; } } } // // Keep the BaseUri for the application definition xaml markup stream. // // If the appdef xaml file is not in the project root directory, the baseUri for this // xaml file is not same as PackAppBaseUri. // // If StartupUri is set to a relative Uri, it should be resolved against this // ApplicationMarkupBaseUri before the uri is passed to NavigationService methods. // internal Uri ApplicationMarkupBaseUri { get { if (_applicationMarkupBaseUri == null) { _applicationMarkupBaseUri = BaseUriHelper.BaseUri; } return _applicationMarkupBaseUri; } set { _applicationMarkupBaseUri = value; } } #endregion Internal Properties //------------------------------------------------------ // // Private Methods // //----------------------------------------------------- #region Private Methods //// Sets up several things on startup. If you want to use avalon services without using the // Application class you will need to call this method explicitly. Standard avalon applications // will not have to worry about this detail. // //// Critical: Adds ResourceContainer to PreloadedPackages. // TreatAsSafe: ResourceContainer is a well-known package and allowed to be added // to PreloadedPackages. Also, the package is not going to be handed out from this // API surface and as such will be protected // [SecurityCritical, SecurityTreatAsSafe] private static void ApplicationInit() { _globalLock = new object(); // Add an instance of the ResourceContainer to PreloadedPackages so that PackWebRequestFactory can find it // and mark it as thread-safe so PackWebResponse won't protect returned streams with a synchronizing wrapper PreloadedPackages.AddPackage(PackUriHelper.GetPackageUri(BaseUriHelper.PackAppBaseUri), new ResourceContainer(), true); MimeObjectFactory.Register(MimeTypeMapper.BamlMime, new StreamToObjectFactoryDelegate(AppModelKnownContentFactory.BamlConverter)); StreamToObjectFactoryDelegate xamlFactoryDelegate = new StreamToObjectFactoryDelegate(AppModelKnownContentFactory.XamlConverter); MimeObjectFactory.Register(MimeTypeMapper.XamlMime, xamlFactoryDelegate); MimeObjectFactory.Register(MimeTypeMapper.FixedDocumentMime, xamlFactoryDelegate); MimeObjectFactory.Register(MimeTypeMapper.FixedDocumentSequenceMime, xamlFactoryDelegate); MimeObjectFactory.Register(MimeTypeMapper.FixedPageMime, xamlFactoryDelegate); MimeObjectFactory.Register(MimeTypeMapper.ResourceDictionaryMime, xamlFactoryDelegate); StreamToObjectFactoryDelegate htmlxappFactoryDelegate = new StreamToObjectFactoryDelegate(AppModelKnownContentFactory.HtmlXappConverter); MimeObjectFactory.Register(MimeTypeMapper.HtmMime, htmlxappFactoryDelegate); MimeObjectFactory.Register(MimeTypeMapper.HtmlMime, htmlxappFactoryDelegate); MimeObjectFactory.Register(MimeTypeMapper.XbapMime, htmlxappFactoryDelegate); } // This function returns the resource stream including resource and content file. // This is called by GetContentStream and GetResourceStream. // NOTE: when we can do breaking change, we should consider uniting GetContentStream // with GetResourceStream. Developer should not need to know and be able to get the // stream based on the uri (pack application). ////// Critical:This code calls into PreLoadedPackages.GetPackage and returns the PackagePart /// Based on the security note in PreLoadedPackages.cs, PackagePart or Package should /// never be given out to client. /// [SecurityCritical] private static PackagePart GetResourceOrContentPart(Uri uri) { // Caller examines the input parameter. // It should be either a relative or pack application uri here. Debug.Assert(!uri.IsAbsoluteUri || BaseUriHelper.IsPackApplicationUri(uri)); Uri packAppUri = BaseUriHelper.PackAppBaseUri; Uri resolvedUri = BindUriHelper.GetResolvedUri(packAppUri, uri); // Using PackUriHelper.ValidateAndGetPackUriComponents internal method // to get Package and Part Uri in one step Uri packageUri; Uri partUri; PackUriHelper.ValidateAndGetPackUriComponents(resolvedUri, out packageUri, out partUri); // // ResourceContainer must have been added into the package cache, the code should just // take use of that ResourceContainer instance, instead of creating a new instance here. // ResourceContainer resContainer = (ResourceContainer)GetResourcePackage(packageUri); return resContainer.GetPart(partUri); } ///Helper for getting the pack://application or pack://siteoforigin resource package. /// "application://" or "siteoforigin://" ////// Critical: Entire packages are not to be exposed in partial trust. /// [SecurityCritical] private static Package GetResourcePackage(Uri packageUri) { Package package = PreloadedPackages.GetPackage(packageUri); if (package == null) { Uri packUri = PackUriHelper.Create(packageUri); Invariant.Assert(packUri == BaseUriHelper.PackAppBaseUri || packUri == BaseUriHelper.SiteOfOriginBaseUri, "Unknown packageUri passed: "+packageUri); Invariant.Assert(IsApplicationObjectShuttingDown); throw new InvalidOperationException(SR.Get(SRID.ApplicationShuttingDown)); } return package; } ////// Creates hwndsource so that we can listen to some window msgs. /// ////// Critical: Calls critical code: HwndSource ctor /// TreatAsSafe: Doesn't expose the critical resource in this method. /// The critical data (_parkingHwnd) is marked as critical and tracked that way. /// This hwnd is only created to enable Activated/Deactivated events. Considered safe. /// /// Note: that this event is not currently enabled for browser hosted case ( work that we won't do for v1) /// [SecurityCritical, SecurityTreatAsSafe] private void EnsureHwndSource() { // We don't support Activate, Deactivate, and SessionEnding // events for browser hosted scenarios thus don't create // this HwndSource if BrowserCallbackServices is valid if (BrowserCallbackServices == null && _parkingHwnd == null) { // _appFilterHook needs to be member variable otherwise // it is GC'ed and we don't get messages from HwndWrapper // (HwndWrapper keeps a WeakReference to the hook) _appFilterHook = new HwndWrapperHook(AppFilterMessage); HwndWrapperHook[] wrapperHooks = {_appFilterHook}; _parkingHwnd = new HwndWrapper( 0, 0, 0, 0, 0, 0, 0, "", IntPtr.Zero, wrapperHooks); } } private IntPtr AppFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { IntPtr retInt = IntPtr.Zero; switch ((WindowMessage)msg) { case WindowMessage.WM_ACTIVATEAPP: handled = WmActivateApp(NativeMethods.IntPtrToInt32(wParam)); break; case WindowMessage.WM_QUERYENDSESSION : handled = WmQueryEndSession(lParam, ref retInt); break; default: handled = false; break; } return retInt; } private bool WmActivateApp(Int32 wParam) { int temp = wParam; bool isActivated = (temp == 0? false : true); // Event handler exception continuality: if exception occurs in Activate/Deactivate event handlers, our state would not // be corrupted because no internal state are affected by Activate/Deactivate. Please check Event handler exception continuality // if a state depending on those events is added. if (isActivated == true) { OnActivated(EventArgs.Empty); } else { OnDeactivated(EventArgs.Empty); } return false; } private bool WmQueryEndSession(IntPtr lParam, ref IntPtr refInt) { int reason = NativeMethods.IntPtrToInt32(lParam); bool retVal = false; // Event handler exception continuality: if exception occurs in SessionEnding event handlers, our state would not // be corrupted because no internal state are affected by SessionEnding. Please check Event handler exception continuality // if a state depending on this event is added. SessionEndingCancelEventArgs secEventArgs = new SessionEndingCancelEventArgs( (reason & NativeMethods.ENDSESSION_LOGOFF) != 0? ReasonSessionEnding.Logoff : ReasonSessionEnding.Shutdown ); OnSessionEnding( secEventArgs ); // shut down the app if not cancelled if ( secEventArgs.Cancel == false ) { Shutdown(); // return true to the wnd proc to signal that we can terminate properly refInt = new IntPtr(1); retVal = false; } else { //// This'll stop a user from Logging off and hence is a high trust operation. // Demand high level of trust. // SecurityHelper.DemandUnmanagedCode(); refInt = IntPtr.Zero; // we have handled the event DefWndProc will not be called for this msg retVal = true; } return retVal; } private void InvalidateResourceReferenceOnWindowCollection(WindowCollection wc, ResourcesChangeInfo info) { bool hasImplicitStyles = info.IsResourceAddOperation && HasImplicitStylesInResources; for (int i = 0; i < wc.Count; i++) { // calling thread is the same as the wc[i] thread so synchronously invalidate // resouces, else, post a dispatcher workitem to invalidate resources. if (wc[i].CheckAccess() == true) { // Set the ShouldLookupImplicitStyles flag on the App's windows // to true if App.Resources has implicit styles. if (hasImplicitStyles) wc[i].ShouldLookupImplicitStyles = true; TreeWalkHelper.InvalidateOnResourcesChange(wc[i], null, info); } else { wc[i].Dispatcher.BeginInvoke( DispatcherPriority.Send, (DispatcherOperationCallback) delegate(object obj) { object[] args = obj as object[]; // Set the ShouldLookupImplicitStyles flag on the App's windows // to true if App.Resources has implicit styles. if (hasImplicitStyles) ((FrameworkElement)args[0]).ShouldLookupImplicitStyles = true; TreeWalkHelper.InvalidateOnResourcesChange((FrameworkElement)args[0], null, (ResourcesChangeInfo)args[1]); return null; }, new object[] {wc[i], info} ); } } } private void SetExitCode(int exitCode) { if (_exitCode != exitCode) { _exitCode = exitCode; System.Environment.ExitCode = exitCode; } } ////// Critical: Calls critical code: ShutdownImpl /// [SecurityCritical] private object ShutdownCallback(object arg) { ShutdownImpl(); return null; } ////// This method gets called on dispatch of the Shutdown DispatcherOperationCallback /// ////// Critical: Calls critical code: DoShutdown, Dispatcher.CritcalInvokeShutdown() /// [SecurityCritical] private void ShutdownImpl() { // Event handler exception continuality: if exception occurs in Exit event handler, // our cleanup action is to finish Shutdown since Exit cannot be cancelled. We don't // want user to use throw exception and catch it to cancel Shutdown. try { DoShutdown(); } finally { // Quit the dispatcher if we ran our own. if (_ownDispatcherStarted == true) { Dispatcher.CriticalInvokeShutdown(); } ServiceProvider = null; } } private static bool IsValidShutdownMode(ShutdownMode value) { return value == ShutdownMode.OnExplicitShutdown || value == ShutdownMode.OnLastWindowClose || value == ShutdownMode.OnMainWindowClose; } private void OnPreBPReady(object sender, BPReadyEventArgs e) { NavService.PreBPReady -= new BPReadyEventHandler(OnPreBPReady); NavService.AllowWindowNavigation = false; ConfigAppWindowAndRootElement(e.Content, e.Uri); NavService = null; e.Cancel = true; } ////// Critical:This code calls into GetAppWindow to get RBW /// TreatAsSafe: The window is not exposed. /// [SecurityCritical, SecurityTreatAsSafe] private void ConfigAppWindowAndRootElement(object root, Uri uri) { Window w = root as Window; if (w == null) { //Creates and returns a NavigationWindow for standalone cases //For browser hosted cases, returns the RootBrowserWindow precreated by docobjhost NavigationWindow appWin = GetAppWindow(); //Since we cancel PreBPReady event here, the other navigation events won't fire twice. appWin.Navigate(root, new NavigateInfo(uri)); // To avoid flash and re-layout, call Window.Show() asynchronously, at Normal priority, which // will happen right after navigation to the content completes. Dispatcher.BeginInvoke(DispatcherPriority.Normal, new SendOrPostCallback((window) => { if (!((Window)window).IsDisposed) { ((Window)window).Show(); } }), appWin); } else { // if Visibility has not been set, we set it to true // Also check whether the window is already closed when we get here - applications could close the window // in its constructor. See Window SE bug # 253703 (or DevDiv Dev10 bug #574222) for more details. if (!w.IsVisibilitySet && !w.IsDisposed) { w.Visibility = Visibility.Visible; } } } ////// Critical: Calls IBrowserCallbackServices.ChangeDownloadState which is critical /// TreatAsSafe: Changing the download state is safe /// [SecurityCritical, SecurityTreatAsSafe] private void ChangeBrowserDownloadState(bool newState) { IBrowserCallbackServices ibcs = (IBrowserCallbackServices)this.GetService(typeof(IBrowserCallbackServices)); if (ibcs != null) { // start or stop waving the flag ibcs.ChangeDownloadState(newState); } } ////// Plays a system sound using the PlaySound api. This is a managed equivalent of the /// internet explorer method IEPlaySoundEx() from ieplaysound.cpp. /// /// The name of the sound to play ///true if a sound was successfully played ////// Critical - Calls critical dllimport methdod PlaySound() and critical method GetSystemSound() /// TreatAsSafe - The input string must already exist as a system sound in the registry. /// [SecurityCritical, SecurityTreatAsSafe] private void PlaySound(string soundName) { string soundFile = GetSystemSound(soundName); if (!string.IsNullOrEmpty(soundFile)) { UnsafeNativeMethods.PlaySound(soundFile, IntPtr.Zero, PLAYSOUND_FLAGS); } } ////// Critical - Asserts to access the registry. May return path information which /// could disclose windows directory (ie. c:\windows\media\sound.wav) /// [SecurityCritical] private string GetSystemSound(string soundName) { string soundFile = null; string regPath = string.Format(CultureInfo.InvariantCulture, SYSTEM_SOUNDS_REGISTRY_LOCATION, soundName); PermissionSet permissions = new PermissionSet(null); permissions.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, SYSTEM_SOUNDS_REGISTRY_BASE)); permissions.AddPermission(new EnvironmentPermission(PermissionState.Unrestricted)); permissions.Assert(); try { using (RegistryKey soundKey = Registry.CurrentUser.OpenSubKey(regPath)) { if (soundKey != null) { soundFile = (string)(soundKey.GetValue("")); } } } // When the value of the register key is empty, the IndexOutofRangeException is thrown. // Please see Dev10 bug 586158 for more details. catch (System.IndexOutOfRangeException) { } finally { CodeAccessPermission.RevertAssert(); } return soundFile; } private EventHandlerList Events { get { if (_events == null) { _events = new EventHandlerList(); } return _events; } } // // Check if the current Uri is for the root element in a baml stream which is processed by an // outer LoadBaml. such as it is through Navigate(uri) or LoadComoponent(uri). // private static bool IsComponentBeingLoadedFromOuterLoadBaml(Uri curComponentUri) { bool isRootElement = false; Invariant.Assert(curComponentUri != null, "curComponentUri should not be null"); if (s_NestedBamlLoadInfo != null && s_NestedBamlLoadInfo.Count > 0) { // // Get the top LoadBamlSynInfo from the stack. // NestedBamlLoadInfo loadBamlSyncInfo = s_NestedBamlLoadInfo.Peek() as NestedBamlLoadInfo; if (loadBamlSyncInfo != null && loadBamlSyncInfo.BamlUri != null && loadBamlSyncInfo.BamlStream != null && BindUriHelper.DoSchemeAndHostMatch(loadBamlSyncInfo.BamlUri, curComponentUri)) { string fileInBamlConvert = loadBamlSyncInfo.BamlUri.LocalPath; string fileCurrent = curComponentUri.LocalPath; Invariant.Assert(fileInBamlConvert != null, "fileInBamlConvert should not be null"); Invariant.Assert(fileCurrent != null, "fileCurrent should not be null"); if (String.Compare(fileInBamlConvert, fileCurrent, StringComparison.OrdinalIgnoreCase) == 0) { // // This is the root element of the xaml page which is being loaded to creat a tree // through LoadBaml call by BamlConverter. // isRootElement = true; } else { // We consider Pack://application,,,/page1.xaml refers to the same component as // Pack://application,,,/myapp;Component/page1.xaml. string[] bamlConvertUriSegments = fileInBamlConvert.Split(new Char[] { '/', '\\' }); string[] curUriSegments = fileCurrent.Split(new Char[] { '/', '\\' }); int l = bamlConvertUriSegments.Length; int m = curUriSegments.Length; // The length of the segments should be at least 1, because the first one is empty. Invariant.Assert((l >= 2) && (m >= 2)); int diff = l - m; // The segment length can only be different in one for myapp;Component if (Math.Abs(diff) == 1) { // Check whether the file name is the same. if (String.Compare(bamlConvertUriSegments[l - 1], curUriSegments[m - 1], StringComparison.OrdinalIgnoreCase) == 0) { string component = (diff == 1) ? bamlConvertUriSegments[1] : curUriSegments[1]; isRootElement = BaseUriHelper.IsComponentEntryAssembly(component); } } } } } return isRootElement; } ////// Critical: This code starts dispatcher run /// [SecurityCritical] [DebuggerNonUserCode] // to treat this method as non-user code even when symbols are available private object StartDispatcherInBrowser(object unused) { if (BrowserInteropHelper.IsBrowserHosted) { BrowserInteropHelper.InitializeHostFilterInput(); // This seemingly meaningless try-catch-throw is a workaround for a CLR deficiency/bug in // exception handling. (WOSB 1936603) When an unhandled exception on the main thread crosses // the AppDomain boundary, the p/invoke layer catches it and throws another exception. Thus, // the original exception is lost before the debugger is notified. The result is no managed // callstack whatsoever. The workaround is based on a debugger/CLR feature that notifies of // exceptions unhandled in 'user code'. This works only when the Just My Code feature is enabled // in VS. try { RunDispatcher(null); } catch { throw; } } return null; } ////// Critical: This code starts dispatcher run /// [SecurityCritical] private object RunDispatcher(object ignore) { if (_ownDispatcherStarted) { throw new InvalidOperationException(SR.Get(SRID.ApplicationAlreadyRunning)); } _ownDispatcherStarted = true; Dispatcher.Run(); return null; } #endregion Private Methods //------------------------------------------------------ // // Private Fields // //----------------------------------------------------- #region Private Fields static private object _globalLock; static private bool _isShuttingDown; static private bool _appCreatedInThisAppDomain; static private Application _appInstance; static private Assembly _resourceAssembly; // Keep LoadBamlSyncInfo stack so that the Outer LoadBaml and Inner LoadBaml( ) for the same // Uri share the related information. [ThreadStatic] private static Stacks_NestedBamlLoadInfo = null; private Uri _startupUri; private Uri _applicationMarkupBaseUri; private HybridDictionary _htProps; private WindowCollection _appWindowList; private WindowCollection _nonAppWindowList; private Window _mainWindow; private ResourceDictionary _resources; private bool _ownDispatcherStarted; private NavigationService _navService; private SecurityCriticalDataForSet _appMimeType; private IServiceProvider _serviceProvider; private IBrowserCallbackServices _browserCallbackServices; private SponsorHelper _browserCallbackSponsor; private bool _appIsShutdown; private int _exitCode; private ShutdownMode _shutdownMode = ShutdownMode.OnLastWindowClose; /// /// Critical: Don't want _parkingHwnd to be exposed and used by anyone besides /// this class. /// [SecurityCritical] private HwndWrapper _parkingHwnd; ////// Critical: _appFilterHook is the hook to listen to window messages. /// We want this to be critical so that no one can get it and listen /// to window messages. /// [SecurityCritical] private HwndWrapperHook _appFilterHook; private EventHandlerList _events; private bool _hasImplicitStylesInResources; private static readonly object EVENT_STARTUP = new object(); private static readonly object EVENT_EXIT = new object(); private static readonly object EVENT_SESSIONENDING = new object(); private const SafeNativeMethods.PlaySoundFlags PLAYSOUND_FLAGS = SafeNativeMethods.PlaySoundFlags.SND_FILENAME | SafeNativeMethods.PlaySoundFlags.SND_NODEFAULT | SafeNativeMethods.PlaySoundFlags.SND_ASYNC | SafeNativeMethods.PlaySoundFlags.SND_NOSTOP; private const string SYSTEM_SOUNDS_REGISTRY_LOCATION = @"AppEvents\Schemes\Apps\Explorer\{0}\.current\"; private const string SYSTEM_SOUNDS_REGISTRY_BASE = @"HKEY_CURRENT_USER\AppEvents\Schemes\Apps\Explorer\"; private const string SOUND_NAVIGATING = "Navigating"; private const string SOUND_COMPLETE_NAVIGATION = "ActivatingDocument"; #endregion Private Fields //----------------------------------------------------- // // Private Types // //----------------------------------------------------- #region NavigationStateChange internal enum NavigationStateChange : byte { Navigating, Completed, Stopped, } #endregion NavigationStateChange } #endregion Application Class // // In Navigation(uri) and LoadComponent(uri), below scenarios might occur: // // After a baml stream is passed into LoadBaml( ) call, when instance // of the root element is created, it would call the generated InitializeComponent( ) // which then calls LoadBaml( ) with the baml stream created from the same uri again. // // The LoadBaml( ) triggered by Navigation or LoadComponent(uri) is named as Outer LoadBaml. // The LoadBaml( ) called by IC in ctor of root Element is named as Inner LoadBaml. // // To prevent the baml stream created from the same Uri from being loaded twice, we need // a way to detect whether the Outer LoadBaml and Inner LoadBaml share the same share the // same stream and the same parser context. // internal class NestedBamlLoadInfo { // // ctor of NestedBamlLoadInfo // internal NestedBamlLoadInfo(Uri uri, Stream stream, bool bSkipJournalProperty) { _BamlUri = uri; _BamlStream = stream; _SkipJournaledProperties = bSkipJournalProperty; } #region internal properties // // OuterBamlUri property // internal Uri BamlUri { get { return _BamlUri; } set { _BamlUri = value; } // Code could reset the OuterBamlUri for performance optimization. } // // OuterBamlStream property // internal Stream BamlStream { get { return _BamlStream; } } // // OuterSkipJournaledProperties // internal bool SkipJournaledProperties { get { return _SkipJournaledProperties; } } #endregion #region private field // Keep Uri which is being handled by Outer LoadBaml in this thread. private Uri _BamlUri = null; // Keep the stream which is being handled by Outer LoadBaml for above Uri in this thread. private Stream _BamlStream = null; // Whether or not SkipJournalProperty when a baml stream is handled in Outer LoadBaml. private bool _SkipJournaledProperties = false; #endregion } #region enum ShutdownMode ////// Enum for ShutdownMode /// public enum ShutdownMode : byte { ////// /// OnLastWindowClose = 0, ////// /// OnMainWindowClose = 1, ////// /// OnExplicitShutdown // NOTE: if you add or remove any values in this enum, be sure to update Application.IsValidShutdownMode() } #endregion enum ShutdownMode #region enum ReasonSessionEnding ////// Enum for ReasonSessionEnding /// public enum ReasonSessionEnding : byte { ////// /// Logoff = 0, ////// /// Shutdown } #endregion enum ReasonSessionEnding } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ProxyHelper.cs
- CharStorage.cs
- WebPartMinimizeVerb.cs
- IsolatedStorage.cs
- PersonalizablePropertyEntry.cs
- AsymmetricKeyExchangeDeformatter.cs
- CodeTypeParameterCollection.cs
- FacetEnabledSchemaElement.cs
- SqlDataReader.cs
- TreeViewCancelEvent.cs
- TargetParameterCountException.cs
- BamlLocalizableResource.cs
- EntryIndex.cs
- UrlMappingsSection.cs
- ObjectNavigationPropertyMapping.cs
- XmlStringTable.cs
- DataGridHelper.cs
- PowerModeChangedEventArgs.cs
- PerfProviderCollection.cs
- SymbolType.cs
- CurrencyWrapper.cs
- Scheduling.cs
- ContextStaticAttribute.cs
- TextEditorLists.cs
- DispatcherProcessingDisabled.cs
- FilterEventArgs.cs
- EnumMemberAttribute.cs
- LayoutEditorPart.cs
- HttpServerVarsCollection.cs
- AggregateNode.cs
- BypassElementCollection.cs
- IFlowDocumentViewer.cs
- WindowClosedEventArgs.cs
- FactoryGenerator.cs
- FormatterServices.cs
- CompilerScopeManager.cs
- CustomGrammar.cs
- ToolBarTray.cs
- CompensationDesigner.cs
- SvcMapFileSerializer.cs
- HashRepartitionEnumerator.cs
- PerformanceCounterNameAttribute.cs
- CharEntityEncoderFallback.cs
- DefaultExpressionVisitor.cs
- PageCatalogPartDesigner.cs
- StatusBar.cs
- CellNormalizer.cs
- CreateSequenceResponse.cs
- _TLSstream.cs
- BufferedStream.cs
- FormViewDeletedEventArgs.cs
- TreeViewCancelEvent.cs
- WinEventHandler.cs
- UriTemplateDispatchFormatter.cs
- XmlObjectSerializerWriteContext.cs
- isolationinterop.cs
- ADMembershipProvider.cs
- localization.cs
- SystemResourceKey.cs
- AncestorChangedEventArgs.cs
- FontCacheUtil.cs
- Image.cs
- SqlBulkCopyColumnMappingCollection.cs
- DictionaryManager.cs
- ToolStripPanelRenderEventArgs.cs
- SourceFileInfo.cs
- FileNotFoundException.cs
- AttachedAnnotationChangedEventArgs.cs
- Wrapper.cs
- SelectionProviderWrapper.cs
- ServiceThrottlingElement.cs
- PersonalizablePropertyEntry.cs
- GlyphElement.cs
- SoapMessage.cs
- TreeView.cs
- TextShapeableCharacters.cs
- MatrixIndependentAnimationStorage.cs
- ImageConverter.cs
- HttpListenerRequest.cs
- TranslateTransform3D.cs
- CalendarAutoFormatDialog.cs
- WSHttpSecurity.cs
- ProcessModelInfo.cs
- ChtmlSelectionListAdapter.cs
- PathGeometry.cs
- RevocationPoint.cs
- GradientStopCollection.cs
- PathFigureCollectionValueSerializer.cs
- GenericAuthenticationEventArgs.cs
- FileAccessException.cs
- XmlReturnReader.cs
- UITypeEditor.cs
- ClientSponsor.cs
- FullTrustAssembly.cs
- _DisconnectOverlappedAsyncResult.cs
- CacheAxisQuery.cs
- DataRecord.cs
- ScrollableControl.cs
- OracleNumber.cs
- VSWCFServiceContractGenerator.cs