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