Deployment.cs :  » 2.6.4-mono-.net-core » System.Windows » System » Windows » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Windows 
System.Windows » System » Windows » Deployment.cs
//
// Deployment.cs
//
// Contact:
//   Moonlight List (moonlight-list@lists.ximian.com)
//
// Copyright 2008-2010 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using System;
using System.Globalization;
using System.IO;
using System.Net;
using System.Reflection;
using System.Security;
using System.Threading;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Interop;
using Mono;
using Mono.Xaml;

namespace System.Windows{

  public sealed partial class Deployment : DependencyObject {
    Types types;
    List<Assembly> assemblies;
    Assembly entry_point_assembly;
    string xap_dir;
    int pending_assemblies;
    
    static List<Action> shutdown_actions = new List<Action> ();
    static bool is_shutting_down;
    
    /* thread-safe */
    internal Surface Surface {
      get {
        /* we need to use the thread-safe version of Deployment::GetSurface since this property
         * may get called from several threads. */
        IntPtr surface = NativeMethods.deployment_get_surface_reffed (this.native);
        Surface result;
        
        if (surface == IntPtr.Zero)
          return null;
        
        result = NativeDependencyObjectHelper.FromIntPtr (surface) as Surface;
        
        /* we got a reffed surface, release that ref now that we'll have a managed ref */
        NativeMethods.event_object_unref (surface);
        
        return result;
      }
    }
    
    internal static bool IsShuttingDown {
      get { return is_shutting_down; }
    }
    
    internal static bool Shutdown ()
    {
      lock (shutdown_actions) {
        is_shutting_down = true;
        while (shutdown_actions.Count > 0) {
          Action a;
          a = shutdown_actions [shutdown_actions.Count - 1];
          shutdown_actions.RemoveAt (shutdown_actions.Count - 1);
          a ();
        }
      }
      // Console.WriteLine ("Deployment.Shutdown ()");
      return true;
    }
    
    /* 
     * thread-safe
     * return false if we're shutting down already.
     */
    internal static bool QueueForShutdown (Action a)
    {
      lock (shutdown_actions) {
        if (is_shutting_down)
          return false;
        shutdown_actions.Add (a);
      }
      
      return true;
    }
    
    /* thread-safe */
    internal static void UnqueueForShutdown (Action a)
    {
      lock (shutdown_actions) {
        shutdown_actions.Remove (a);
      }
    }
    
    public static Deployment Current {
      get {
        IntPtr dep = NativeMethods.deployment_get_current ();
        return NativeDependencyObjectHelper.Lookup (Kind.DEPLOYMENT, dep) as Deployment;
      }

      internal set {
        NativeMethods.deployment_set_current (value == null ? IntPtr.Zero : value.native);
      }
    }
  
    public static void RegisterAssembly (Assembly assembly)
    {
      throw new System.NotImplementedException ();
    }
    
    public static void SetCurrentApplication (Application application)
    {
      if ((application == null && Application.IsCurrentSet) ||
        (application != null && Application.IsCurrentSet && Application.Current != application))
        Application.Current.Free ();

      NativeMethods.deployment_set_current_application (Current.native, application == null ? IntPtr.Zero : application.NativeHandle);
    }

    internal Types Types {
      get {
        if (types == null)
          types = new Types (NativeMethods.deployment_get_types (native));
        return types;
      }
    }

    internal List<Assembly> Assemblies {
      get {
        return assemblies;
      }
    }

    internal string XapDir {
      get {
        return xap_dir;
      }
      set {
        xap_dir = value;
      }
    }
    
    internal Assembly EntryAssembly {
      get {
        return entry_point_assembly;
      }
      set {
        entry_point_assembly = value;
      }
    }
    
    void ExtractXap (string xapPath)
    {
      xap_dir = NativeMethods.xap_unpack (xapPath);
      if (xap_dir == null)
        throw new MoonException (2103, "Invalid or malformed application: Check manifest");
    }

    void CompareRuntimeVersions ()
    {
      int[] versions = new int[4];
      string[] version_strings = RuntimeVersion.Split ('.');

      for (int i = 0; i < version_strings.Length; i ++) {
        if (!Int32.TryParse (version_strings[i], out versions[i]))
          throw new MoonException (2105, "invalid RuntimeVersion");
      }

      if (versions[0] == 2) {
        /* SL2 accepts anything newer than 2.0.30524.0 */
        if (version_strings.Length > 1)
          if (versions[1] != 0)
            throw new MoonException (2106, "Failed to load the application. It was built with an obsolete version of Silverlight");

        if (version_strings.Length > 2)
          if (versions[2] <= 30524)
            throw new MoonException (2106, "Failed to load the application. It was built with an obsolete version of Silverlight");
      }
      else if (versions[0] == 3) {
        // we need to add validation stuff for SL3 rtm here
      }
      else if (versions[0] == 4) {
        // we don't actually validate any 4.0
        // runtime versions yet since there's
        // no telling what it'll be at RTM.
      }
      else {
        throw new MoonException (2105, "invalid RuntimeVersion");
      }
    }

    void ReadManifest ()
    {
      XamlLoader loader = XamlLoader.CreateManagedXamlLoader (null, Surface.Native, PluginHost.Handle);
      string app_manifest = Path.Combine (XapDir, "appmanifest.xaml");

      if (!File.Exists (app_manifest))
        throw new MoonException(2103, "Invalid or malformed application: Check manifest");

      string app_manifest_contents;

      using (StreamReader r = new StreamReader (app_manifest))
        app_manifest_contents = r.ReadToEnd();

      using (var v = Value.FromObject (this)) {
        try {
          loader.Hydrate (v, app_manifest_contents);
        } catch (Exception e) {
          throw new MoonException (7016, e.Message);
        }
      }

      if (RuntimeVersion == null)
        throw new MoonException (2105, "No RuntimeVersion specified in AppManifest");

      CompareRuntimeVersions ();

      if (EntryPointAssembly == null)
        throw new MoonException (2103, "Invalid or malformed application: Check manifest");

      if (EntryPointType == null)
        throw new Exception ("No entrypoint defined in the AppManifest.xaml");

      try {
        // this is a "set once" property, we set it to its default in case it was not part of the manifest
        ExternalCallersFromCrossDomain = CrossDomainAccess.NoAccess;
      }
      catch (ArgumentException) {
        // a value was already set (should be quite rare)
      }
    }

    internal bool InitializeDeployment (string culture, string uiCulture) {
      TerminateCurrentApplication ();

      try {
        if (culture != null && culture.ToLower () != "auto")
          Thread.CurrentThread.CurrentCulture = new CultureInfo (culture);
        if (uiCulture != null && uiCulture.ToLower() != "auto")
          Thread.CurrentThread.CurrentUICulture = new CultureInfo (uiCulture);
      }
      catch (Exception e) {
        // 2105 is required by the Localization drt (#352)
        throw new MoonException (2105, e.Message);
      }

      EntryPointType = "System.Windows.Application";
      EntryPointAssembly = typeof (Application).Assembly.GetName ().Name;
      EntryAssembly = typeof (Application).Assembly;
      return LoadAssemblies ();
    }
      
    internal bool InitializeDeployment (IntPtr plugin, string xapPath, string culture, string uiCulture) {
      TerminateCurrentApplication ();

      try {
        if (culture != null && culture.ToLower () != "auto")
          Thread.CurrentThread.CurrentCulture = new CultureInfo (culture);
        if (uiCulture != null && uiCulture.ToLower() != "auto")
          Thread.CurrentThread.CurrentUICulture = new CultureInfo (uiCulture);
      }
      catch (Exception e) {
        // 2105 is required by the Localization drt (#352)
        throw new MoonException (2105, e.Message);
      }

      if (plugin == IntPtr.Zero) {
        string location = NativeMethods.surface_get_source_location (Surface.Native);
        // full uri including xap
        Uri source_uri = new Uri (location, UriKind.RelativeOrAbsolute);

        // IsolatedStorage (inside mscorlib.dll) needs some information about the XAP file
        // to initialize it's application and site directory storage. WebClient is another user of this
        AppDomain.CurrentDomain.SetData ("xap_uri", PluginHost.GetApplicationIdentity (source_uri));
      }
      else {
        PluginHost.SetPluginHandle (plugin);
      }
      
      if (!Directory.Exists (xapPath))
        ExtractXap (xapPath);
      else
        XapDir = xapPath;
      
      // this is currently disabled for the 3.0 desktop profile.  we'll
      // need it to be done by unmanaged code there, on every deployment
      // switch.
#if NET_2_1
      AppDomain.CurrentDomain.SetupInformationNoCopy.ApplicationBase = XapDir;
#endif

      ReadManifest ();

      NativeMethods.deployment_set_is_loaded_from_xap (native, true);
      return LoadAssemblies ();
    }

    // note: throwing MoonException from here is ok since this code is called (sync) from the plugin
    internal bool LoadAssemblies ()
    {
      assemblies = new List <Assembly> ();
      assemblies.Add (typeof (Application).Assembly);
      
      pending_assemblies = Parts != null ? Parts.Count : 0;

      for (int i = 0; i < ExternalParts.Count; i++) {
        ExtensionPart ext = ExternalParts[i] as ExtensionPart;

        if (ext != null) {
          try {
            // TODO These ExternalPart assemblies should really be placed in
            // a global long term cache but simply make sure we load them for now
            Console.WriteLine ("Attempting To Load ExternalPart {0}", ext.Source);

            DownloadAssembly (ext.Source, 2152);

            pending_assemblies++;
          } catch (Exception e) {
            int error = (e is MethodAccessException) ? 4004 : 2152;
            throw new MoonException (error, string.Format ("Error while loading the '{0}' ExternalPart: {1}", ext.Source, e.Message));
          }
        }
      }

      for (int i = 0; Parts != null && i < Parts.Count; i++) {
        var source = Parts [i].Source;

        try {
          bool try_downloading = false;
          string canon = Helper.CanonicalizeAssemblyPath (source);
          string filename = Path.GetFullPath (Path.Combine (XapDir, canon));
          // note: the content of the AssemblyManifest.xaml file is untrusted
          if (filename.StartsWith (XapDir)) {
            try {
              Assembly asm = Assembly.LoadFrom (filename);
              AssemblyRegister (asm);
              if (pending_assemblies == 0)
                return true;
            } catch (FileNotFoundException) {
              try_downloading = true;
            }
          } else {
            // we can hit a Part with a relative URI starting with a '/' which fails the above test
            try_downloading = true;
          }

          if (!try_downloading)
            continue;

          DownloadAssembly (new Uri (source, UriKind.RelativeOrAbsolute), 2105);
        } catch (Exception e) {
          int error = (e is MethodAccessException) ? 4004 : 2105;
          throw new MoonException (error, string.Format ("Error while loading the '{0}' assembly : {1}", source, e.Message));
        }
      }

      // unmanaged (JS/XAML only) applications can go directly to create the application
      return pending_assemblies == 0 ? CreateApplication () : true;
    }

    void DownloadAssembly (Uri uri, int errorCode)
    {
      Uri xap = new Uri (NativeMethods.plugin_instance_get_source_location (PluginHost.Handle));
      // WebClient deals with relative URI but HttpWebRequest does not
      // but we need the later to detect redirection
      if (!uri.IsAbsoluteUri) {
        uri = new Uri (xap, uri);
      } else if (xap.Scheme != uri.Scheme) {
        throw new SecurityException ("Cross scheme URI downloading " + uri.ToString ());
      }
      HttpWebRequest req = (HttpWebRequest) WebRequest.Create (uri);
      req.BeginGetResponse (AssemblyGetResponse, new object[] { req, errorCode });
    }

    // note: throwing MoonException from here is NOT ok since this code is called async
    // and the exception won't be reported, directly, to the caller
    void AssemblyGetResponse (IAsyncResult result)
    {
      object[] tuple = (object []) result.AsyncState;
      WebRequest wreq = (WebRequest) tuple [0];
      int error_code = (int) tuple [1];
      try {
        HttpWebResponse wresp = (HttpWebResponse) wreq.EndGetResponse (result);

        if (wresp.StatusCode != HttpStatusCode.OK) {
          wresp.Close ();
          EmitError (error_code, String.Format ("Error while downloading the '{0}'.", wreq.RequestUri));
          return;
        }

        if (wresp.ResponseUri != wreq.RequestUri) {
          wresp.Close ();
          EmitError (error_code, "Redirection not allowed to download assemblies.");
          return;
        }

        Stream responseStream = wresp.GetResponseStream ();

        AssemblyPart a = new AssemblyPart ();
        Assembly asm = a.Load (responseStream);

        if (asm == null) {
          // it's not a valid assembly, try to unzip it.
          using (MemoryStream ms = new MemoryStream ()) {
            ManagedStreamCallbacks source_cb;
            ManagedStreamCallbacks dest_cb;
            StreamWrapper source_wrapper;
            StreamWrapper dest_wrapper;

            responseStream.Seek (0, SeekOrigin.Begin);

            source_wrapper = new StreamWrapper (responseStream);
            dest_wrapper = new StreamWrapper (ms);

            source_cb = source_wrapper.GetCallbacks ();
            dest_cb = dest_wrapper.GetCallbacks ();

            // the zip files I've come across have a single file in them, the
            // dll.  so we assume that any/every zip file will contain a single
            // file, and just get the first one from the zip file directory.
            if (NativeMethods.managed_unzip_stream_to_stream_first_file (ref source_cb, ref dest_cb)) {
              ms.Seek (0, SeekOrigin.Begin);
              asm = a.Load (ms);
            }
          }
        }

        wresp.Close ();

        if (asm != null)
          Dispatcher.BeginInvoke (new AssemblyRegistration (AssemblyRegister), asm);
        else
          EmitError (2153, String.Format ("Error while loading '{0}'.", wreq.RequestUri));
      }
      catch (Exception e) {
        // we need to report everything since any error means CreateApplication won't be called
        EmitError (error_code, e.ToString ());
      }
    }

    delegate void AssemblyRegistration (Assembly asm);

    // note: only access 'assemblies' from the main thread
    void AssemblyRegister (Assembly assembly)
    {
      assemblies.Add (assembly);
      SetEntryAssembly (assembly);

      pending_assemblies--;
      
      if (pending_assemblies == 0)
        CreateApplication ();        
    }

    // extracted since NativeMethods.surface_emit_error is security critical
    internal void EmitError (int errorCode, string message)
    {
      // FIXME: 8 == EXECUTION_ENGINE_EXCEPTION code.  should it be something else?
      INativeDependencyObjectWrapper app = Application.Current;
      if (Thread.CurrentThread == DependencyObject.moonlight_thread) {
        NativeMethods.surface_emit_error (Surface.Native, 8, errorCode, message);
      } else {
        Dispatcher.BeginInvoke (() => {
          // call again but, this time, from main thread
          EmitError (errorCode, message);
        });
      }
    }

    // extracted since Assembly.GetName is security critical
    void SetEntryAssembly (Assembly asm)
    {
      if (string.Equals (asm.GetName ().Name, EntryPointAssembly, StringComparison.OrdinalIgnoreCase))
        EntryAssembly = asm;
    }

    void TerminateCurrentApplication ()
    {
      if (Application.Current != null) {
        Application.Current.Terminate ();
      }
      if (Deployment.Current != null && Deployment.Current.Surface != null)
        NativeMethods.surface_attach (Deployment.Current.Surface.Native, IntPtr.Zero);
    }

    // will be called when all assemblies are loaded (can be async for downloading)
    // which means we need to report errors to the plugin, since it won't get it from calling managed code
    internal bool CreateApplication ()
    {
      SetCurrentApplication (null);

      if (EntryAssembly == null) {
        EmitError (2103, "Could not find the entry point assembly") ;
        return false;
      }

      Type entry_type = EntryAssembly.GetType (EntryPointType);
      if (entry_type == null) {
        EmitError (2103, String.Format ("Could not find the startup type {0} on the {1}", 
          EntryPointType, EntryPointAssembly));
        return false;
      }

      if (!entry_type.IsSubclassOf (typeof (Application)) && entry_type != typeof (Application)) {
#if SANITY
        Type t = entry_type;
        int spacing = 0;
        while (t != null) {
          if (spacing > 0) {
            for (int i = 0; i < spacing; i ++)
              Console.Write (" ");
            Console.Write ("+ ");
          }
          Console.WriteLine ("{0}", t);
          spacing += 2;
          t = t.BaseType;
        }
#endif

        EmitError (2103, "Startup type does not derive from System.Windows.Application");
        return false;
      }
      
      foreach (Assembly a in Assemblies)
        Application.LoadXmlnsDefinitionMappings (a);

      Application instance = null;

      try {
        instance = (Application) Activator.CreateInstance (entry_type);
      } catch {
        EmitError (2103, String.Format ("Error while creating the instance of type {0}", entry_type));
        return false;
      }

      SetCurrentApplication (instance);

      StartupEventArgs args = new StartupEventArgs();
      instance.OnStartup (args);

      return true;
    }

    internal event EventHandler LayoutUpdated {
      add {
        RegisterEvent (EventIds.Deployment_LayoutUpdatedEvent, value, Events.CreateNullSenderEventHandlerDispatcher (value));
      }
      remove {
        UnregisterEvent (EventIds.Deployment_LayoutUpdatedEvent, value);
      }
    }

    [System.ComponentModel.EditorBrowsable (System.ComponentModel.EditorBrowsableState.Never)]
    public static string GetAppIdForUri (Uri AppUri, out string xapLocationStr)
    {
      Console.WriteLine ("System.Windows.Deployment.GetAppIdForUri ({0}): Not implemented (returning empty string)", AppUri);
      /* Returning "" for now to try to avoid any NREs */
      xapLocationStr = string.Empty;
      return string.Empty;
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.