转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/

本来的想法是做一个可以自动卸载并且部署新solution到SharePoint farm的tool。但是最后只做到retract成功和remove solution之前这个阶段。因为一个原因(等待solution retracted的过程中出现CLR方面的问题)导致不能将整个过程连续起来,这是相关的博问,希望有高手可以解惑。

下面的tool将会根据SharePoint solution wsp文件名自动识别solution,并在相应的站点deactive相应的site collection级别的solution feature,然后在SharePoint farm中卸载相应的solution。

图形界面:

选择Web Application,选择其下的Site Collection,然后填写登陆SharePoint Site的用户名和密码,选择要卸载的wsp文件。之后点击OK,就会自动进行卸载。

待完成的部分(已经都注释掉了)用是从等待retract成功开始,然后remove solution,deploy solution,以及active feature的过程。难点主要是等待solution retract成功。希望SharePoint方面专家可以帮助解决这个问题。相关的详细异常信息,请见博问。

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.IO;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support;
using OpenQA.Selenium.Support.UI;
using Selenium;
using System.Net;
using System.Runtime.InteropServices;
using System.Globalization;namespace SharePoint_Solution_Auto_Deploy
{public partial class MainForm : Form{//To make the GetForegroundWindow possible.[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]public static extern IntPtr GetForegroundWindow();//Form entry.public MainForm(){InitializeComponent();getSPWebApps(); }//Add web apps to the combobox.private void getSPWebApps(){try{SPSecurity.RunWithElevatedPrivileges(() =>{foreach (SPWebApplication webApp in SPWebService.ContentService.WebApplications){WebAppComBox.Items.Add(webApp.Name);}});}catch (Exception ex){WriteLog(ex);}}//Web application.private void WebAppsComBox_SelectedIndexChanged(object sender, EventArgs e){WebAppComBox.Text = WebAppComBox.SelectedItem.ToString();SPWebApplicationCollection webApps = SPWebService.ContentService.WebApplications;SPWebApplication webApp = webApps[WebAppComBox.Text];getSPSites(webApp);}//Site.private void getSPSites(SPWebApplication webApp){SPSiteCollection sites = webApp.Sites;//Clear old items from the combox first and then add the new items into it.
            SiteComBox.Items.Clear();foreach (SPSite site in sites){SiteComBox.Items.Add(site.Url.ToString());}}//Write log method.private static void WriteLog(Exception ex){string logUrl = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\SeleniumAutoTest.txt";if (File.Exists(@logUrl)){using (FileStream fs = new FileStream(logUrl, FileMode.Append)){using (StreamWriter sw = new StreamWriter(fs, Encoding.Default)){try{sw.Write(ex);}catch (Exception ex1){WriteLog(ex1);}finally{sw.Close();fs.Close();}}}}else{using (FileStream fs = new FileStream(logUrl, FileMode.CreateNew)){using (StreamWriter sw = new StreamWriter(fs, Encoding.Default)){try{sw.Write(ex);}catch (Exception ex1){WriteLog(ex1);}finally{sw.Close();fs.Close();}}}}}//Select the wsp file action.private void select_wsp_button_Click(object sender, EventArgs e){OpenFileDialog wspFile = new OpenFileDialog();if (wspFile.ShowDialog() == DialogResult.OK) {WspText.Text = wspFile.FileName;}}//Retract and deploy action.private void ok_button_Click(object sender, EventArgs e){//1.Login site and deactive the feature.IWebDriver iw = new InternetExplorerDriver();iw = login(iw, SiteComBox.Text.ToString(), UserNameText.Text.ToString(), PwdText.Text.ToString());INavigation navi = iw.Navigate();//Go to the site collection features page.navi.GoToUrl(SiteComBox.Text.ToString() + "/_layouts/15/ManageFeatures.aspx?Scope=Site");//Judge the feature category by the name wsp file selected.string category;var wspPath = WspText.Text.ToString().Split(new Char[] { '\\' });category = wspPath[wspPath.Count() - 1];//MessageBox.Show(category.ToString());//Deactive the feature.
            deactivateFeature(iw, category);//2.If has solution, retract first.string solutionPageUrl = "http://wdsinpexca:10000/_admin/Solutions.aspx";navi.GoToUrl(solutionPageUrl);iw.FindElement(By.LinkText(category.ToLower())).Click();waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_solutionStatusToolBar_RptControls_LinkRetractSolution_LinkText");iw.FindElement(By.Id("ctl00_PlaceHolderMain_solutionStatusToolBar_RptControls_LinkRetractSolution_LinkText")).Click();waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_ctl02_RptControls_BtnSubmit");iw.FindElement(By.Id("ctl00_PlaceHolderMain_ctl02_RptControls_BtnSubmit")).Click();//During the retracting period, there will be a down. Let's sleep to get over it.//Thread.Sleep(300000);//Back to the wsp page.
            iw.FindElement(By.LinkText(category.ToLower())).Click();iw.Navigate().Refresh();//Wait for the solution retracted.//waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_solutionStatusToolBar_RptControls_LinkRemoveSolution_LinkText");//iw.FindElement(By.Id("ctl00_PlaceHolderMain_solutionStatusToolBar_RptControls_LinkRemoveSolution_LinkText")).Click();//Click OK in the popup window.//IntPtr myPtr = GetForegroundWindow();//if (myPtr != IntPtr.Zero)//{//    System.Windows.Forms.SendKeys.SendWait("{ENTER}");//}//3.Deploy the solution to the web app.//4.Active the site wsp feature.
}//Deactive the feature accourding to the wsp solution category.private void deactivateFeature(IWebDriver iw,string category){if (category == "APPSSP2013MISite.wsp"){//Deactive the MISITE feature.waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_featact_rptrFeatureList_ctl21_ctl00_divFeatureStatus");string featureStatus = iw.FindElement(By.Id("ctl00_PlaceHolderMain_featact_rptrFeatureList_ctl21_ctl00_divFeatureStatus")).GetAttribute("featurestatus").ToString();if (featureStatus == "Active"){waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_featact_rptrFeatureList_ctl21_ctl00_btnActivate");iw.FindElement(By.Id("ctl00_PlaceHolderMain_featact_rptrFeatureList_ctl21_ctl00_btnActivate")).Click();waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_lnkbtnDeactivate");iw.FindElement(By.Id("ctl00_PlaceHolderMain_lnkbtnDeactivate")).Click();}}//Other solutions can be extended here.
        }//Wait until page-element loaded method.private static void waitUntilPageLoaded(IWebDriver iw, string element){try{iw.FindElement(By.Id(element));}catch (Exception ex){WriteLog(ex);//Refresh the current page.//iw.Navigate().Refresh();Thread.Sleep(1000);waitUntilPageLoaded(iw, element);}}//Login SP site method.public static IWebDriver login(IWebDriver driver, string url,string userName,string pwd){INavigation navigation = driver.Navigate();navigation.GoToUrl(url);//driver.FindElement(By.Id("overridelink")).Click();IntPtr myPtr = GetForegroundWindow();//IntPtr hWnd = FindWindow(null, "abc");if (myPtr != IntPtr.Zero){//Send message to the window.
                System.Windows.Forms.SendKeys.SendWait(userName);System.Windows.Forms.SendKeys.SendWait("{TAB}");System.Windows.Forms.SendKeys.SendWait(pwd);System.Windows.Forms.SendKeys.SendWait("{ENTER}");}return driver;}}
}

View Code

因为不知道怎么一气呵成,于是我把Retract和Retract之后的事情拆开来做,就有了下面的:

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.IO;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support;
using OpenQA.Selenium.Support.UI;
using Selenium;
using System.Net;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Management.Automation;
using System.Management.Automation.Runspaces;namespace SharePoint_Solution_Auto_Deploy
{public partial class MainForm : Form{//To make the GetForegroundWindow possible.[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]public static extern IntPtr GetForegroundWindow();//Form entry.public MainForm(){InitializeComponent();getSPWebApps(); }//Add web apps to the combobox.private void getSPWebApps(){try{SPSecurity.RunWithElevatedPrivileges(() =>{foreach (SPWebApplication webApp in SPWebService.ContentService.WebApplications){WebAppComBox.Items.Add(webApp.Name);}});}catch (Exception ex){WriteLog(ex);}}//Web application.private void WebAppsComBox_SelectedIndexChanged(object sender, EventArgs e){WebAppComBox.Text = WebAppComBox.SelectedItem.ToString();SPWebApplicationCollection webApps = SPWebService.ContentService.WebApplications;SPWebApplication webApp = webApps[WebAppComBox.Text];getSPSites(webApp);}//Site.private void getSPSites(SPWebApplication webApp){SPSiteCollection sites = webApp.Sites;//Clear old items from the combox first and then add the new items into it.
            SiteComBox.Items.Clear();foreach (SPSite site in sites){SiteComBox.Items.Add(site.Url.ToString());}}//Write log method.private static void WriteLog(Exception ex){string logUrl = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\SeleniumAutoTest.txt";if (File.Exists(@logUrl)){using (FileStream fs = new FileStream(logUrl, FileMode.Append)){using (StreamWriter sw = new StreamWriter(fs, Encoding.Default)){try{sw.Write(ex);}catch (Exception ex1){WriteLog(ex1);}finally{sw.Close();fs.Close();}}}}else{using (FileStream fs = new FileStream(logUrl, FileMode.CreateNew)){using (StreamWriter sw = new StreamWriter(fs, Encoding.Default)){try{sw.Write(ex);}catch (Exception ex1){WriteLog(ex1);}finally{sw.Close();fs.Close();}}}}}//Select the wsp file action.private void select_wsp_button_Click(object sender, EventArgs e){OpenFileDialog wspFile = new OpenFileDialog();if (wspFile.ShowDialog() == DialogResult.OK) {WspText.Text = wspFile.FileName;}}//Retract and deploy action.private void ok_button_Click(object sender, EventArgs e){if (WebAppComBox.Text == "" || SiteComBox.Text == "" || UserNameText.Text == "" || PwdText.Text == "" || WspText.Text == "" || CAText.Text == ""){MessageBox.Show("You can not leave any box blank. Please check your input.");}else{//1.Login site and deactive the feature.IWebDriver iw = new InternetExplorerDriver();iw = login(iw, SiteComBox.Text.ToString(), UserNameText.Text.ToString(), PwdText.Text.ToString());INavigation navi = iw.Navigate();//Go to the site collection features page.navi.GoToUrl(SiteComBox.Text.ToString() + "/_layouts/15/ManageFeatures.aspx?Scope=Site");//Judge the feature category by the name wsp file selected.string category;var wspPath = WspText.Text.ToString().Split(new Char[] { '\\' });category = wspPath[wspPath.Count() - 1];//MessageBox.Show(category.ToString());//Deactive the feature.
                deactivateFeature(iw, category);//2.If has solution, retract first.string solutionPageUrl = CAText.Text + "/_admin/Solutions.aspx";navi.GoToUrl(solutionPageUrl);iw.FindElement(By.LinkText(category.ToLower())).Click();waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_solutionStatusToolBar_RptControls_LinkRetractSolution_LinkText");iw.FindElement(By.Id("ctl00_PlaceHolderMain_solutionStatusToolBar_RptControls_LinkRetractSolution_LinkText")).Click();waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_ctl02_RptControls_BtnSubmit");iw.FindElement(By.Id("ctl00_PlaceHolderMain_ctl02_RptControls_BtnSubmit")).Click();//During the retracting period, there will be a down. Let's sleep to get over it.//Thread.Sleep(300000);//Back to the wsp page.
                iw.FindElement(By.LinkText(category.ToLower())).Click();iw.Navigate().Refresh();iw.Close();}}//Deactive the feature accourding to the wsp solution category.private void deactivateFeature(IWebDriver iw,string category){if (category == "APPSSP2013MISite.wsp"){//Deactive the MISITE feature.waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_featact_rptrFeatureList_ctl21_ctl00_divFeatureStatus");string featureStatus = iw.FindElement(By.Id("ctl00_PlaceHolderMain_featact_rptrFeatureList_ctl21_ctl00_divFeatureStatus")).GetAttribute("featurestatus").ToString();if (featureStatus == "Active"){waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_featact_rptrFeatureList_ctl21_ctl00_btnActivate");iw.FindElement(By.Id("ctl00_PlaceHolderMain_featact_rptrFeatureList_ctl21_ctl00_btnActivate")).Click();waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_lnkbtnDeactivate");iw.FindElement(By.Id("ctl00_PlaceHolderMain_lnkbtnDeactivate")).Click();}}//Other solutions can be extended here.
        }//Wait until page-element loaded method.private static void waitUntilPageLoaded(IWebDriver iw, string element){try{iw.FindElement(By.Id(element));}catch (Exception ex){WriteLog(ex);//Refresh the current page.//iw.Navigate().Refresh();Thread.Sleep(1000);waitUntilPageLoaded(iw, element);}}//Login SP site method.public static IWebDriver login(IWebDriver driver, string url,string userName,string pwd){INavigation navigation = driver.Navigate();navigation.GoToUrl(url);//driver.FindElement(By.Id("overridelink")).Click();IntPtr myPtr = GetForegroundWindow();//IntPtr hWnd = FindWindow(null, "abc");if (myPtr != IntPtr.Zero){//Send message to the window.
                System.Windows.Forms.SendKeys.SendWait(userName);System.Windows.Forms.SendKeys.SendWait("{TAB}");System.Windows.Forms.SendKeys.SendWait(pwd);System.Windows.Forms.SendKeys.SendWait("{ENTER}");}return driver;}//Remove the solution from the farm.private void remove_button_Click(object sender, EventArgs e){if (WspText.Text == "" || CAText.Text == ""){MessageBox.Show("You can not leave the 'WSP' and 'Central Admin' box blank.");}else{IWebDriver iw = new InternetExplorerDriver();INavigation navi = iw.Navigate();navi.GoToUrl(CAText.Text + "/_admin/Solutions.aspx");waitUntilPageLoaded(iw, "__gvctl00_PlaceHolderMain_GvItems__div");string category;var wspPath = WspText.Text.ToString().Split(new Char[] { '\\' });category = wspPath[wspPath.Count() - 1];iw.FindElement(By.LinkText(category.ToLower())).Click();waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_solutionStatusToolBar_RptControls_LinkRemoveSolution_LinkText");iw.FindElement(By.Id("ctl00_PlaceHolderMain_solutionStatusToolBar_RptControls_LinkRemoveSolution_LinkText")).Click();//Click OK in the popup window.IntPtr myPtr = GetForegroundWindow();if (myPtr != IntPtr.Zero){System.Windows.Forms.SendKeys.SendWait("{ENTER}");}iw.Close();}}//Deploy the solution.private void deploy_button_Click(object sender, EventArgs e){if (WspText.Text == "" || CAText.Text == ""){MessageBox.Show("You can not leave the 'WSP' and 'Central Admin' box blank.");}else{//Open the PowerShell.SPSecurity.RunWithElevatedPrivileges(() =>{using (Runspace runspace = RunspaceFactory.CreateRunspace()){//MessageBox.Show("Run PowerShell.");
                        runspace.Open();PowerShell ps = PowerShell.Create();ps.Runspace = runspace;Pipeline pipeline = runspace.CreatePipeline();pipeline.Commands.AddScript("Add-PSSnapin microsoft.sharepoint.powershell");string cmd = "Add-SPSolution " + WspText.Text.ToString();pipeline.Commands.AddScript(cmd);pipeline.Invoke();}});//Go to the solution-deploy page.IWebDriver iw = new InternetExplorerDriver();INavigation navi = iw.Navigate();navi.GoToUrl(CAText.Text + "/_admin/Solutions.aspx");waitUntilPageLoaded(iw, "__gvctl00_PlaceHolderMain_GvItems__div");string category;var wspPath = WspText.Text.ToString().Split(new Char[] { '\\' });category = wspPath[wspPath.Count() - 1];iw.FindElement(By.LinkText(category.ToLower())).Click();waitUntilPageLoaded(iw, "ctl00_PlaceHolderMain_solutionStatusToolBar_RptControls_LinkDeploySolution_LinkText");iw.FindElement(By.Id("ctl00_PlaceHolderMain_solutionStatusToolBar_RptControls_LinkDeploySolution_LinkText")).Click();iw.FindElement(By.Id("ctl00_PlaceHolderMain_ctl02_RptControls_BtnSubmit")).Click();}}}
}

View Code

至此,Deactivate Feature,Retract Solution,Remove Solution,Deploy Solution的过程就已经封装好了。至于Active Feature由于界面大小有限就不写了,和Deactivate Feature的过程是一样的。

SharePoint自动化系列——Solution auto-redeploy using Selenium(C#)相关推荐

  1. SharePoint自动化系列——通过Coded UI录制脚本自动化创建SharePoint Designer Reusable Workflow...

    Coded UI非常好,我开始还在想,怎么样能让一个通过SharePoint Designer创建的Workflow publish三百五十次?想不到一个好的方法,也不知道SharePoint Des ...

  2. SharePoint自动化系列——Add/Remove Record from items

    转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 目的:批量的将SharePoint items变成records或者将records变成普通的it ...

  3. SharePoint自动化系列——Error features自动deactivate

    转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ SharePoint Content Deployment prerequisite--Error ...

  4. SharePoint自动化系列——通过PowerShell创建SharePoint Lists

    转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 代码如下(保存到本地ps1文件中,右键run with PowerShell即可): Add-PS ...

  5. 软测自动化之Firefox火狐浏览器安装selenium IDE插件(一)

    系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:软测自动化之Firefox火狐浏览器安装selenium IDE插件(一) 提示:写完文章后,目录可以自动生成,如 ...

  6. php配合jade使用,前端自动化系列(四)之jade预编译html

    刚开始写这篇文章的时候: 其实我是拒绝的: 因为在 前端自动化系列(二)之less.scss.sass.stylus css预处理器 中: 我已经表明了我的态度: 我是不喜欢那种靠缩进来体现等级层次感 ...

  7. 出于一些原因的考虑,即日起,一步一步SharePoint 2007系列文章将暂停发布

    非常抱歉的告诉大家,出于一些原因的考虑,即日起,一步一步SharePoint 2007系列文章将暂停发布,恢复发布的时间大致确定在11月上旬.希望朋友们能原谅! 感谢朋友们的一贯支持! 转载于:htt ...

  8. Python 自动化,Helium 凭什么取代 Selenium?

    1. Helium 是什么? Helium 是一款 Web 端自动化开源框架,全称是: Selenium-Python-Helium , 从名字上 就可以看出, Helium 似乎和 Selenium ...

  9. SharePoint自动化部署,利用PowerShell 导入用户至AD——PART II

    这是对上一篇文章<SharePoint自动化部署,利用PowerShell 导出/导入AD中的用户>进行补充.开发时,为了测试和演示,我们往往需要经常性的把用户添加到AD中.数据量小的时候 ...

最新文章

  1. [备忘]几种即见即所得Web编辑器优缺点比较
  2. Ubuntu18.04 MariaDB
  3. MATLAB之简谐信号声音的生成及其调制性
  4. TextView跑步灯效果及在特殊情况下无效的解决方案
  5. strlen()函数 与 “\0“ 的关系 与 利用;strcmp()
  6. C#中的delegate的 Invoke 、BeginInvoke的区别
  7. 51nod 1343 行列式的根
  8. 机器学习相关知识 大佬博客整理
  9. oracle 导出 cuow,直通伍伦贡大学的升学保障— 伍伦贡大学学院(UOWC)
  10. 英语答题测试的软件叫什么,英语做题软件哪个好 有答案解析的英语做题软件分享...
  11. Oracle表空间大小的限制和DB_BLOCK_SIZE的概念
  12. Linux模拟超级终端minicom
  13. SimpleDateFormat类的线程安全问题和解决方案
  14. 新疆特岗计算机考试题,2020新疆特岗教师笔试资料领取(小学信息技术)
  15. 50道编程小题目之【分解质因数】
  16. 剑指offer java -查找旋转数组的最小数字
  17. 解决Eclipse 64位启动时,报jvm.dll错
  18. 外卖返利小程序源码下载 美团/饿了么小程序源码下载
  19. 物联网常见的无线传输协议类型
  20. 利用 Python 优雅地将 PDF 转换成图片

热门文章

  1. 服务器php 不能运行框架,经验总结 PHP框架常见错误
  2. mysql integrityerror_mysql插入数据报错IntegrityError: (1062, Duplicate entry 'xx' for key 'xxxxx')...
  3. ant指定servlet版本_阅读SpringMVC源码前,不妨看下简易版本SpringMVC框架的搭建
  4. oracle强大的包,ORACLE 程序包
  5. super.getClass()方法调用返回结果的原因
  6. 一步一步部署SSIS包图解教程1
  7. 母板页中的图片路径及页面链接路径设置
  8. 计算机基础知识:原码、反码、补码
  9. C_C++指针指针应用详解
  10. sql 2008 R2添加对MySql的远程服务器链接