168 строки
6.9 KiB
C#
168 строки
6.9 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="XboxConsoleAdapterBase.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//------------------------------------------------------------------------------
|
|
|
|
namespace Microsoft.Internal.GamesTest.Xbox.Adapter
|
|
{
|
|
using System;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Reflection;
|
|
using Microsoft.Internal.GamesTest.Utilities;
|
|
using Microsoft.Internal.GamesTest.Xbox.Exceptions;
|
|
using Microsoft.Internal.GamesTest.Xbox.Interfaces;
|
|
|
|
/// <summary>
|
|
/// The base class for all XboxConsole adapters. This class provides default a implementation
|
|
/// for all parts of the Xbox Console API, even if they are not supported by one particular
|
|
/// version of the XDK (in which case an exception is thrown). It is assumed that the adapter
|
|
/// for each version of the XDK will override the pieces of functionality that are available or
|
|
/// different in that particular build.
|
|
/// </summary>
|
|
public abstract partial class XboxConsoleAdapterBase : DisposableObject
|
|
{
|
|
private const string NotSupportedMessage = "The feature that you are trying to use is not supported by the version of the XDK installed on your machine.";
|
|
|
|
private static bool isStaticInitialized = false;
|
|
private static object staticInitializationLock = new object();
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the XboxConsoleAdapterBase class.
|
|
/// </summary>
|
|
/// <param name="toolsIpAddress">The "Tools Ip" address of the Xbox kit.</param>
|
|
/// <param name="xboxXdk">The XboxXdk functional facade implementation.</param>
|
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "Required by design.")]
|
|
protected XboxConsoleAdapterBase(IPAddress toolsIpAddress, IXboxXdk xboxXdk)
|
|
{
|
|
if (toolsIpAddress == null)
|
|
{
|
|
throw new ArgumentNullException("toolsIpAddress");
|
|
}
|
|
|
|
if (xboxXdk == null)
|
|
{
|
|
throw new ArgumentNullException("xboxXdk");
|
|
}
|
|
|
|
this.XboxXdk = xboxXdk;
|
|
this.ThrowIfXdkNotInstalled();
|
|
|
|
if (!isStaticInitialized)
|
|
{
|
|
lock (staticInitializationLock)
|
|
{
|
|
if (!isStaticInitialized)
|
|
{
|
|
this.Initialize();
|
|
isStaticInitialized = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.ToolsIpAddress = toolsIpAddress;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the tools IP address of the kit to be controlled.
|
|
/// </summary>
|
|
public IPAddress ToolsIpAddress { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets the XboxXdk functional facade implementation.
|
|
/// </summary>
|
|
protected IXboxXdk XboxXdk { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets the path to the root folder of XDK.
|
|
/// </summary>
|
|
protected virtual string PathToXdk
|
|
{
|
|
get
|
|
{
|
|
return Environment.GetEnvironmentVariable("DurangoXdk");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the path to the "bin" folder of XDK.
|
|
/// </summary>
|
|
protected virtual string PathToXdkBin
|
|
{
|
|
get
|
|
{
|
|
return Path.Combine(this.PathToXdk, "bin");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Throws XdkNotFoundException if XDK is not properly installed.
|
|
/// </summary>
|
|
protected virtual void ThrowIfXdkNotInstalled()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(this.PathToXdk))
|
|
{
|
|
throw new XdkNotFoundException("Failed to find a value for the \"DurangoXdk\" environment variable. Ensure that the XDK is installed.");
|
|
}
|
|
|
|
string xdkBinDir = this.PathToXdkBin;
|
|
if (!Directory.Exists(xdkBinDir))
|
|
{
|
|
throw new XdkNotFoundException(string.Format(CultureInfo.InvariantCulture, "Failed to find the expected directory containing XDK binary files. Ensure this directory exists: '{0}'", xdkBinDir));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the adapter.
|
|
/// </summary>
|
|
protected virtual void Initialize()
|
|
{
|
|
this.SetNativeDllSearchPath(this.PathToXdkBin);
|
|
this.SubscribeToAssemblyResolve(this.PathToXdkBin);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets native Dll search path.
|
|
/// </summary>
|
|
/// <param name="durangoXdkBinDirectory">The complete path to the XDK's "bin" directory.</param>
|
|
protected void SetNativeDllSearchPath(string durangoXdkBinDirectory)
|
|
{
|
|
if (!NativeMethods.SetDllDirectory(durangoXdkBinDirectory))
|
|
{
|
|
throw new InitializationFailedException("Call to Win32 function \"SetDllDirectory\" failed. Failed to set the directory used to modify the search path for native DLLs.");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Subscribes to current AppDomain's AssemblyResolve event.
|
|
/// </summary>
|
|
/// <param name="durangoXdkBinDirectory">The name of the XDK binary directory environment variable.</param>
|
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Justification = "We need to manually load the XTF assemblies from the XDK.")]
|
|
protected void SubscribeToAssemblyResolve(string durangoXdkBinDirectory)
|
|
{
|
|
// We have purposely chosen not to include the Microsoft.Xbox.Xtf.* assemblies
|
|
// with this library because at the time of this writing Durango is still
|
|
// super-secret and we don't want to be distributing the platform team's
|
|
// code. Therefore, we need to locate the assemblies on the user's
|
|
// machine at run-time.
|
|
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
|
|
{
|
|
AssemblyName assemblyName = new AssemblyName(args.Name);
|
|
string fileName = assemblyName.Name + ".dll";
|
|
string filePath = Path.Combine(durangoXdkBinDirectory, fileName);
|
|
if (!File.Exists(filePath))
|
|
{
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
Assembly a = Assembly.LoadFrom(filePath);
|
|
return a;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|