在开发Windows Phone 7(WP7)应用时,开发者经常需要在设备上部署和测试应用程序。Visual Studio提供了部署项目的功能,但有时需要在没有Visual Studio环境的情况下部署XAP文件。本文将介绍如何构建自己的WP7部署应用,以便更灵活地部署应用程序。
在开始之前,确保开发环境中已经安装了必要的组件。
为了与WP7设备进行通信,需要将Microsoft.SmartDevice.Connectivity.dll添加到项目中。这个DLL文件通常位于以下路径:
C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.SmartDevice.Connectivity\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.SmartDevice.Connectivity.dll
使用DatastoreManager类可以获取所有连接到计算机的WP7设备。以下是获取设备列表的代码示例:
    static IEnumerable<object> GetDevices()
    {
        var manager = new DatastoreManager(CultureInfo.CurrentUICulture.LCID);
        return manager.GetPlatforms().SelectMany(platform => platform.GetDevices()).Cast<object>().ToArray();
    }
    
每个XAP文件(类似于ZIP文件)都包含一个名为WMAppManifest.xml的文件,其中包含了应用程序的所有信息。以下是解析XAP文件并提取应用程序信息的代码示例:
    private const string FileFilter = "WMAppManifest.xml";
    private XapInfo GetXapInformation(string xapPath)
    {
        try
        {
            var fastZip = new FastZip();
            var tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            fastZip.ExtractZip(xapPath, tempFile, FileFilter);
            var files = Directory.GetFiles(tempFile);
            if (files.Length == 0) return null;
            using (Stream stream2 = File.OpenRead(files[0]))
            {
                var document = new XPathDocument(stream2);
                var selectSingleNode = document.CreateNavigator().SelectSingleNode("//App");
                if (selectSingleNode != null)
                {
                    return new XapInfo(selectSingleNode, files[0], xapPath);
                }
            }
        }
        catch { }
        return null;
    }
    
创建一个XapInfo类来存储部署所需的所有数据。以下是XapInfo类的代码示例:
    public class XapInfo
    {
        public Guid Guid { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public string Version { get; set; }
        public string Author { get; set; }
        public string Publisher { get; set; }
        public string IconPath { get; set; }
        public string XapFilePath { get; set; }
        public XapInfo(XPathNavigator node, string filePath, string xapFile)
        {
            this.Guid = new Guid(node.GetAttribute("ProductID", string.Empty));
            this.Title = node.GetAttribute("Title", string.Empty);
            this.Description = node.GetAttribute("Description", string.Empty);
            this.Version = node.GetAttribute("Version", string.Empty);
            this.Author = node.GetAttribute("Author", string.Empty);
            this.Publisher = node.GetAttribute("Publisher", string.Empty);
            this.IconPath = GetXapIcon(xapFile);
            this.XapFilePath = xapFile;
        }
        private const string IconFilter = "ApplicationIcon.png";
        private string GetXapIcon(string xapPath)
        {
            string iconPath;
            try
            {
                var fastZip = new FastZip();
                var tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                fastZip.ExtractZip(xapPath, tempFile, IconFilter);
                var files = Directory.GetFiles(tempFile);
                if (files.Length == 0) return null;
                var fileStream = File.OpenRead(files[0]) ?? Assembly.GetExecutingAssembly().GetManifestResourceStream(IconFilter);
                var tempFileName = Path.GetTempFileName();
                using (var stream3 = new FileStream(tempFileName, FileMode.Create))
                {
                    fileStream.CopyTo(stream3);
                }
                iconPath = tempFileName;
            }
            catch (Exception)
            {
                iconPath = null;
            }
            return iconPath;
        }
    }
    
    var device = (Device)e.Argument;
    try
    {
        device.Connect();
        if (device.IsApplicationInstalled(_xapInfo.Guid.Value))
        {
            device.GetApplication(_xapInfo.Guid.Value).Uninstall();
        }
        device.InstallApplication(_xapInfo.Guid.Value, _xapInfo.Guid.Value, "NormalApp", _xapInfo.IconPath, _xapInfo.XapFilePath);
        device.Disconnect();
    }
    catch (SmartDeviceException ex)
    {
        MessageBox.Show(ex.Message, "Deploy Application", MessageBoxButton.OK, MessageBoxImage.Information);
    }