SharePoint solution auto-retract using Selenium(C#)

---恢复内容开始---

本来的想法是做一个可以自动卸载并且部署新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;
        }
    }
}
时间: 2024-08-27 15:02:20

SharePoint solution auto-retract using Selenium(C#)的相关文章

SharePoint下自定义WFC服务

同事忙不过来,呼叫我支援做一个关于项目的展现页面,项目可以嵌套. 打算采用js + 服务模式做. 为什么采取这种模式, 原因之一,第三方的数据库,不是SharePoint列表, 第二,POC这种修改比较平凡的东西,做好服务后,就可以采取前端模板随意玩. 至于前端模板,可以用backbone, Angular这种等,也可以采用Jquery插件, easyui这种,还可以 react,jsrender这种轻量级的View. 然后兴致勃勃的开始了,一开始发现, What? 数据库没有主键 , 大家也知

Sharepoint学习笔记—习题系列--70-576习题解析 -(Q147-Q151)

Question  147 Your company has an existing SharePoint 2010 public-facing Web site. The Web site runs on multiple loadbalanced Web front-ends. Your company recently changed its name. You are asked to design a plan to update the Web site content to ref

SharePoint开发部署WSP解决方案包

注:本文所讲内容以SharePoint2013版本为例,开发工具以VS2013为基础.历史版本也可以参考本文. WSP:SharePoint Solution Package 解决方案包. 一.概念和工具 我们先引出WSP的由来.要想深入了解WSP,要先从SharePoint开发说起.SharePoint可开发的内容比较杂,最新版本的VS2013中已经包含了Sharepoint解决方案的基本模板,从创建到部署整个过程简单易用,比起以前开发解决方案要容易多了.但还是不能脱离SharePoint宿主

开启貌似已经过时很久的新坑:SharePoint服务器端对象模型

5年前(嗯,是5年前),SharePoint 2010刚发布的时候,曾经和kaneboy试图一起写一本关于SharePoint 2010开发的书,名字叫<SharePoint 2010 应用开发指南>(涂指南这个名字不是白叫的).给大家看一下当年列出来的大纲: SharePoint 2010开发概览 SharePoint 2010基础架构,SharePoint与ASP.NET.IIS的关系 解释服务器场的概念,从硬件拓扑层次解释APP.WFE 解释Web应用程序.网站集.网站.列表和文档库的概

想学习SharePoint,需要准备哪些方面的准备?--写给SharePoint新人

如果你是一个纯的SharePoint新手,想从事SharePoint行业,那么应该准备哪些技术呢? 首先要明确将来的发展方向是什么,一般来说有两个: 1.      IT Pro 根据客户的实际情况,设计和搭建SharePoint场环境,优化SharePoint场,提供基于SharePoint的解决方案 2.      Developer 根据客户需求,开发出解决方案 不同的方向,学习的重点也就不一样了.不过不管哪条路,最开始也要先熟悉SharePoint的安装和使用. 如果是IT Pro,建议

[转]SharePoint 2013 App 开发 (2) - 建立开发环境

这篇文章属于SharePoint 2013 App开发系列文章,到这篇文章为止,此系列的文章包括: SharePoint 2013 App开发 (1) - 什么是SharePoint App? SharePoint 2013 App开发 (2) - 建立开发环境 (本文) 在开发SharePoint App之前,开发人员需要有一个SharePoint开发环境.无论是开发何种类型的应用程序,开发人员都需要在开发机器上准备相应的开发环境.比如,如果是开发ASP.NET Web应用,那么在开发机器上除

[it-ebooks]电子书列表

#### it-ebooks电子书质量不错,但搜索功能不是很好 #### 格式说明  [ ]中为年份      ||  前后是标题和副标题  #### [2014]: Learning Objective-C by Developing iPhone Games || Leverage Xcode and Objective-C to develop iPhone games http://it-ebooks.info/book/3544/ Learning Web App Developmen

(转) [it-ebooks]电子书列表

[it-ebooks]电子书列表 [2014]: Learning Objective-C by Developing iPhone Games || Leverage Xcode and Objective-C to develop iPhone games http://it-ebooks.info/book/3544/Learning Web App Development || Build Quickly with Proven JavaScript Techniques http://

Error occurred in deployment step ‘Retract Solution‘: xxx 无法反序列化,因为它没有公共的默认构造函数

一.环境:SharePoint 2016 + Visual Studio 2015, 二.错误描述: 错误1:帮朋友写个计时器Demo,部署位置GAC,来回部署几次后,vs2015报错: 严重性 代码 说明 项目 文件 行 禁止显示状态错误 Error?occurred?in?deployment?step?'Retract?Solution':?SP_CustomTimerJob.ListTimerJob?无法反序列化,因为它没有公共的默认构造函数. ? 错误2:打开管理中心-监控-复查作业,