SPS2003中的个人网站是可以被备份和恢复的。这样在我们把个人网站恢复到其他服务器上以后,文档等数据不会丢失。 但个人网站上的连接,以及订阅,却是没有办法保留的。如果是把个人网站搬到新的服务器上也就算了,但在下面这种情况下,可能会觉得有些冤: 我们在一台SPS服务器上建立了个人网站,然后又打开了“共享服务”,把个人网站放到另一台服务器上。此时,会发现所有的个人网站都被重建了,连结和订阅也都丢失! 这种情况下,我们可以尝试下面的代码。下面的代码仅供参考,有何建议可以随时给我发信。当然,请使用英文,此Blog的email不支持中文。 应用程序源代码: using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using Microsoft.SharePoint; using Microsoft.SharePoint.Portal; using Microsoft.SharePoint.Portal.Topology; using Microsoft.SharePoint.Portal.UserProfiles; using Microsoft.SharePoint.Portal.Alerts; using System.Runtime.Serialization.Formatters.Soap; using System.IO; using System.Runtime.Serialization.Formatters.Binary; namespace mysiteinfo { /// <summary> /// Summary description for Form1. /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Button button1; private System.Windows.Forms.TextBox origportal; private System.Windows.Forms.TextBox newportal; private System.Windows.Forms.TextBox domaintext; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label3; private System.Windows.Forms.Label label4; private System.Windows.Forms.Button button2; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public Form1() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.origportal = new System.Windows.Forms.TextBox(); this.newportal = new System.Windows.Forms.TextBox(); this.domaintext = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); this.button2 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // button1 // this.button1.Location = new System.Drawing.Point(32, 200); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(88, 40); this.button1.TabIndex = 0; this.button1.Text = "Save"; this.button1.Click += new System.EventHandler(this.button1_Click); // // origportal // this.origportal.Location = new System.Drawing.Point(64, 104); this.origportal.Name = "origportal"; this.origportal.Size = new System.Drawing.Size(168, 20); this.origportal.TabIndex = 2; this.origportal.Text = "http://servername/"; // // newportal // this.newportal.Location = new System.Drawing.Point(64, 152); this.newportal.Name = "newportal"; this.newportal.Size = new System.Drawing.Size(168, 20); this.newportal.TabIndex = 3; this.newportal.Text = "http://servername:90/"; // // domaintext // this.domaintext.Location = new System.Drawing.Point(64, 24); this.domaintext.Name = "domaintext"; this.domaintext.Size = new System.Drawing.Size(72, 20); this.domaintext.TabIndex = 4; this.domaintext.Text = "domainname"; // // label1 // this.label1.Location = new System.Drawing.Point(8, 24); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(48, 23); this.label1.TabIndex = 6; this.label1.Text = "domain"; // // label3 // this.label3.Location = new System.Drawing.Point(8, 104); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(56, 32); this.label3.TabIndex = 8; this.label3.Text = "Original Portal"; // // label4 // this.label4.Location = new System.Drawing.Point(8, 152); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(56, 24); this.label4.TabIndex = 9; this.label4.Text = "New Portal"; // // button2 // this.button2.Location = new System.Drawing.Point(136, 200); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(88, 40); this.button2.TabIndex = 10; this.button2.Text = "Add"; this.button2.Click += new System.EventHandler(this.button2_Click); // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(292, 273); this.Controls.Add(this.button2); this.Controls.Add(this.label4); this.Controls.Add(this.label3); this.Controls.Add(this.label1); this.Controls.Add(this.domaintext); this.Controls.Add(this.newportal); this.Controls.Add(this.origportal); this.Controls.Add(this.button1); this.Name = "Form1"; this.Text = "MySiteInfo"; this.ResumeLayout(false); } #endregion /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } private void button1_Click(object sender, System.EventArgs e) { string origstrUrl = origportal.Text; TopologyManager tm = new TopologyManager(); PortalSite ps = tm.PortalSites[new Uri(origstrUrl)]; PortalContext pc = PortalApplication.GetContext(ps); AlertManager am = new AlertManager(pc); UserProfileManager upm = new UserProfileManager(pc); IEnumerator itr=upm.GetEnumerator(); Stream file=File.Create("c:\\atest.xml"); SoapFormatter serializer = new SoapFormatter(); Hashtable aTable=new Hashtable(); while(itr.MoveNext()) { UserProfile u=((UserProfile)itr.Current); QuickLinkManager qlm = u.QuickLinks; AlertCollection ac = u.Alerts; LoadEntry aEntry=new LoadEntry(); string name=u.PersonalSite.Owner.LoginName; saveUserProfile(u,aEntry); aTable.Add(name,aEntry); } serializer.Serialize(file,aTable); file.Close(); } private void saveUserProfile(UserProfile aUserProfile,LoadEntry aEntry) { UserProfile u = aUserProfile; QuickLinkManager qlm = u.QuickLinks; AlertCollection ac = u.Alerts; foreach (QuickLink ql in qlm) { LoadQLinks myqlinkload = new LoadQLinks(); myqlinkload.Title = ql.Title.ToString(); myqlinkload.URL = ql.URL.ToString(); myqlinkload.Group = ql.Group.ToString(); if(aEntry.Links==null)aEntry.Links=new ArrayList(); aEntry.Links.Add(myqlinkload); } foreach(Alert a in ac) { LoadAlert myalertload = new LoadAlert(); myalertload.TypeId = a.Type.TypeId.ToString(); myalertload.Name = a.Name.ToString(); myalertload.ObjectDisplayName = a.ObjectDisplayName.ToString(); myalertload.ObjectUrl = a.ObjectUrl.ToString(); myalertload.ConditionText = a.ConditionText.ToString(); myalertload.Query = a.Query.ToString(); if(aEntry.Alerts==null)aEntry.Alerts=new ArrayList(); aEntry.Alerts.Add(myalertload); } } private void button2_Click(object sender, System.EventArgs e) { TopologyManager tm = new TopologyManager(); string newstrUrl = newportal.Text; PortalSite newps = tm.PortalSites[new Uri(newstrUrl)]; PortalContext newpc = PortalApplication.GetContext(newps); UserProfileManager newupm = new UserProfileManager(newpc); Stream file=File.OpenRead("c:\\atest.xml"); SoapFormatter deserializer=new SoapFormatter(); try { Hashtable aTable=(Hashtable)deserializer.Deserialize(file); IEnumerator itr=aTable.Keys.GetEnumerator(); while(itr.MoveNext()) { string sAccount = (string)itr.Current; if (!newupm.UserExists(sAccount)) newupm.CreateUserProfile(sAccount); UserProfile newu = newupm.GetUserProfile(sAccount); LoadEntry aEntry=(LoadEntry)aTable[sAccount]; ReLoadUesrProfile(newu,aEntry); } } catch { } } public void ReLoadUesrProfile(UserProfile newu,LoadEntry aEntry) { SoapFormatter deserializer = new SoapFormatter(); QuickLinkManager newqlm = newu.QuickLinks; AlertCollection newac = newu.Alerts; LoadQLinks myqlinkload = new LoadQLinks(); LoadAlert myalertload = new LoadAlert(); for(int i=0;i<aEntry.Links.Count;i++) { myqlinkload = (LoadQLinks)aEntry.Links[i]; newqlm.Add(myqlinkload.Title.ToString(), myqlinkload.URL.ToString(), myqlinkload.Group.ToString(), true); } for(int i=0;i<aEntry.Alerts.Count;i++) { myalertload = (LoadAlert)aEntry.Alerts[i]; Alert newalert; switch(myalertload.TypeId.ToLower()) { case "list": newalert = newac.CreateAlert("Microsoft.SharePoint.Portal.Alerts.Types.ListAlertType"); FillAlertProp(myalertload,newalert); break; case "search": newalert = newac.CreateAlert("Microsoft.SharePoint.Portal.Alerts.Types.SearchAlertType"); FillAlertProp(myalertload,newalert); break; case "area": newalert = newac.CreateAlert("Microsoft.SharePoint.Portal.Alerts.Types.AreaAlertType"); FillAlertProp(myalertload,newalert); break; case "document": newalert = newac.CreateAlert("Microsoft.SharePoint.Portal.Alerts.Types.DocumentAlertType"); FillAlertProp(myalertload,newalert); break; case "listing": newalert = newac.CreateAlert("Microsoft.SharePoint.Portal.Alerts.Types.ListingAlertType"); FillAlertProp(myalertload,newalert); break; case "alistitem": newalert = newac.CreateAlert("Microsoft.SharePoint.Portal.Alerts.Types.ListitemAlertType"); FillAlertProp(myalertload,newalert); break; case "person": newalert = newac.CreateAlert("Microsoft.SharePoint.Portal.Alerts.Types.PersonAlertType"); FillAlertProp(myalertload,newalert); break; case "siteregistry": newalert = newac.CreateAlert("Microsoft.SharePoint.Portal.Alerts.Types.SiteRegistryAlertType"); FillAlertProp(myalertload,newalert); break; default: break; } } } public void FillAlertProp(LoadAlert myalertload,Alert newalert) { newalert.Name = myalertload.Name.ToString(); newalert.ObjectDisplayName = myalertload.ObjectDisplayName.ToString(); newalert.ObjectUrl = myalertload.ObjectUrl.ToString(); newalert.ConditionText = myalertload.ConditionText.ToString(); newalert.Query = myalertload.Query.ToString(); newalert.DeliveryChannels.Add(new PortalChannelSettings()); newalert.Commit(); newalert.Activate (); } } } 调用的类的源代码: using System; using Microsoft.SharePoint.Portal.Alerts; using Microsoft.SharePoint.Portal; using System.Collections; namespace mysiteinfo { /// <summary> /// Summary description for Load. /// </summary> [Serializable] public class LoadQLinks { public string Title; public string URL; public string Group; } [Serializable] public class LoadAlert { public string TypeId; public string Name; public string ObjectDisplayName; public string ObjectUrl; public string ConditionText; public string Query; } [Serializable] public class LoadEntry { public ArrayList Links; public ArrayList Alerts; } }