o(╯□╰)o 其实蛮简单的,算是献丑了。
SharePoint 2013中的应用其实就是一个基于OpenXML的压缩包,你可以将后缀名从app修改为zip,然后就可以看到里面的结构了。
主要是三个文件:AppManifest.xml、AppIcon.png、AppIcon.png.config.xml。通过OpenXML的工具,还可以查看到他们互相之间还有关系(Relationship)。
然后就简单了,先建立一个可以序列化成XML格式的类AppDefinition(这里的类是最简单的,即不包含权限等信息)。如果你想要更专业些,可以根据SharePoint App Manifest (Schema map)中的XML Schema Definition(XSD)生成一个AppDefinition的类,用来序列化。
[XmlRoot("App", Namespace = "http://schemas.microsoft.com/sharepoint/2012/app/manifest")] public class AppDefinition { [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("ProductID")] public string ProductID { get; set; } [XmlAttribute("Version")] public string Version { get; set; } [XmlAttribute("SharePointMinVersion")] public string SharePointMinVersion { get; set; } [XmlElement] public AppProperties Properties { get; set; } [XmlElement(ElementName = "AppPrincipal")] public AppPrincipal Principal { get; set; } [XmlRoot] public class AppProperties { [XmlElement] public string Title { get; set; } [XmlElement] public string StartPage { get; set; } } [XmlRoot] public class AppPrincipal { [XmlElement] public RemoteWebApplication RemoteWebApplication { get; set; } } [XmlRoot] public class RemoteWebApplication { [XmlAttribute("ClientId")] public string ClientId { get; set; } } }
然后通过XmlSerializer即可将实例化后的AppDefinition(definition)序列化为AppManifest.xml了。
AppDefinition definition = new AppDefinition() { Name = Guid.NewGuid().ToString(), ProductID = Guid.NewGuid().ToString("B"), Version = "1.0.0.0", SharePointMinVersion = "15.0.0.0", Properties = new AppDefinition.AppProperties() { Title = title, StartPage = launchUrl }, Principal = new AppDefinition.AppPrincipal { RemoteWebApplication = new AppDefinition.RemoteWebApplication { ClientId = Guid.NewGuid().ToString("B"), } } };
using (XmlWriter writer = XmlTextWriter.Create(partStream, new XmlWriterSettings() { Encoding = Encoding.UTF8, Indent = true })) { XmlSerializer serializer = new XmlSerializer(typeof(AppDefinition)); serializer.Serialize(writer, definition); }
最后用System.IO.Packaging下的Package类,打包就可以了。
using (Package package = Package.Open(stream, FileMode.Create)) { PackagePart manifestPart = package.CreatePart<AppDefinition>(new Uri("/AppManifest.xml", UriKind.Relative), "text/xml", definition); PackagePart iconPart = package.CreatePart<string>(new Uri("/AppIcon.png", UriKind.Relative), "application/wsp", path); PackagePart configPart = package.CreatePart<AppPartConfig>(new Uri("/AppIcon.png.config.xml", UriKind.Relative), "text/xml", config); package.CreateRelationship(manifestPart.Uri, TargetMode.Internal, "http://schemas.microsoft.com/sharepoint/2012/app/relationships/package-manifest"); manifestPart.CreateRelationship(iconPart.Uri, TargetMode.Internal, "http://schemas.microsoft.com/sharepoint/2012/app/relationships/manifest-icon"); iconPart.CreateRelationship(configPart.Uri, TargetMode.Internal, "http://schemas.microsoft.com/sharepoint/2012/app/relationships/partconfiguration"); }
O(∩_∩)O~~ 如果你能看懂并且会用到的话,就拿去玩吧。示例代码在这里下载。
参阅:
Explore the app manifest and the package of an app for SharePoint