在开发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);
}