When deploying master pages i use this feature event receiver to fix up the many possible things that can go wrong when deploying master pages via features.
public class LayoutsFeatureReceiver : Microsoft.SharePoint.SPFeatureReceiver {
public override void FeatureActivated(SPFeatureReceiverProperties properties) {
object parent = properties.Feature.Parent;
if (parent is SPSite) {
SPSite site = (SPSite)parent
using (SPWeb web = site.RootWeb) {
SPElementDefinitionCollection elementDefinitionCollection = properties.Definition.GetElementDefinitions(new CultureInfo(1033));
foreach (SPElementDefinition elementDefinition in elementDefinitionCollection) {
XmlNode elementrootnode = elementDefinition.XmlDefinition;
_FeatureActivated(elementrootnode, properties.Feature.Definition.RootDirectory, web);
}
}
}
}
public static void _FeatureActivated(XmlNode elementrootnode, string rootdirectory, SPWeb web) {
XmlNamespaceManager ns = new XmlNamespaceManager(elementrootnode.OwnerDocument.NameTable);
ns.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/");
XmlNodeList nodes2 = elementrootnode.SelectNodes(".//sp:Property[@Name='FixUpFile']", ns);
foreach (XmlNode node2 in nodes2) {
bool yesno = node2.Attributes["Value"].Value == "TRUE";
string name = node2.ParentNode.Attributes["Url"].Value;
string url = node2.ParentNode.ParentNode.Attributes["Url"].Value + "/" + name;
if (yesno) {
SPFile file = web.GetFile(url);
if (file.Exists) {
if (file.CheckOutStatus != SPFile.SPCheckOutStatus.None) {
try {
file.UndoCheckOut();
} catch (SPException ex) {
if (ex.ToString().IndexOf("You cannot discard check out because there is no checked in version of the document. Please delete this document instead.") != -1) {
file.Delete();
} else {
throw ex;
}
}
}
if (file.CustomizedPageStatus == SPCustomizedPageStatus.Customized) {
file.RevertContentStream();
}
if (file.CustomizedPageStatus == SPCustomizedPageStatus.None) {
string rawdata = Path.Combine(rootdirectory, url);
byte[] data = File.ReadAllBytes(rawdata);
if (data.Length == 0) {
data = new byte[1];
}
file.CheckOut();
file.SaveBinary(data);
file.Update();
file.CheckIn("LayoutsFeatureReceiver:SaveBinary");
if (file.Item.ModerationInformation != null) {
file.Approve("LayoutsFeatureReceiver:SaveBinary");
}
}
file = web.GetFile(url);
if (file.CustomizedPageStatus != SPCustomizedPageStatus.Uncustomized) {
//err: failed to re-ghost page
}
} else {
//err: file not provision'ed, most likely a user has created a file but not check'ed it in
}
}
}
}
}
Add the FixUpFile property to your master page element definition to trigger the fix up
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="MasterPagesModule"
Url="_catalogs/masterpage"
RootWebOnly="True"
Path="_catalogs\masterpage">
<File Url="custom.master"
IgnoreIfAlreadyExists="TRUE"
Type="GhostableInLibrary">
<Property Name="ContentType" Value="$Resources:cmscore,contenttype_masterpage_name;" />
<Property Name="Title" Value="Custom master page." />
<Property Name="FixUpFile" Value="TRUE" />
</File>
</Module>
</Elements>