使用C#代码部署SharePoint 2013开发包简单总结(一)

      这篇文章将总结下如何将自己开发的列表、Web部件、事件接收器等元素部署到SharePoint的服务器。因水平有限,我的做法未必是最佳实践,会有些错误理解和疏漏,欢迎各位高手批评指正——但一定要能给出更好的方案。如果您是SharePoint开发的新手,希望能和我一起积极的思考,也欢迎您的讨论。

      首先写个简单的通过PowerShell部署Web部件的例子。当我写了一个SharePoint 2013 的可视化Web部件,在Visual Studio 2012发布后,将得到一个wsp文件(这是个压缩文件),例如叫VisualWebPartProject1.wsp。然后我们打开SharePoint 2013 Management Shell,输入下面的命令,这个Web部件就可以使用了!

1

2

3

Add-SPSolution –LiteralPath C:\VisualWebPartProject1.wsp

Install-SPSolution -Identity VisualWebPartProject1.wsp   -WebApplication "SharePoint - 80" -GACDeployment –FullTrustBinDeployment

Enable-SPFeature -Identity c63aa2e6-527e-4de4-8e99-1729f2d052aa -Url http://sp2013-01:80/

 

      从上面的PowerShell命令,我们可以看出做了三件事儿:1、添加解决方案包(Add-SPSolution);  2、部署解决方案包(Install-SPSolution);  3、激活功能(Enable-SPFeature)。(参数细节请参考http://technet.microsoft.com/zh-cn/library/ee906565.aspx)。

      一定有很多人会觉得PowerShell部署已经很简单,但是我总觉得PowerShell命令不好记也不好写。而且有时需要技术不专业的人帮忙(例如客户IT)会多费不少口舌,不如把它做成一个exe文件,把参数写到XML里配置好,这样实施人员一双击执行文件就OK了。

     下面我们就研究下如何用C#代码完成这部署三大步骤,不过之前要介绍几个重要的.NET类型!

1、SPFarm:服务器场, 可通过SPFarm.Local获取本地服务器场对象。

2、SPWebApplication:Web应用程序,可以通过SPWebService.ContentService.WebApplications获取它们的集合,也可以在这个集合中用它的Name属性找到您想要的对象。

3、SPSite:网站集,可以传参网站集URL给SPSite的构造方法创建对象,也可以通过SPWebApplication对象的Sites属性获取集合。

4、SPWeb:网站/子网站,每个SPSite对象有一个RootWeb属性,是它的根网站;还有个AllWebs属性,是它的所有网站。每个SPWeb对象也有个Webs属性,是这个网站的子网站。

5、SPSolution:解决方案,我们开发项目生成的wsp文件就靠它来管理,SPFarm对象有个Solutions的属性,是解决方案的集合。在SharePoint管理中心主页(SharePoint 2013 Central Administration)-〉系统设置(System Settings)-〉场管理(Farm Management)-〉管理场解决方案(Manage farm solutions)能看到已上传的解决方案。更多了解解决方案包请参考http://technet.microsoft.com/zh-cn/library/cc262995(v=office.14).aspx。

6、SPFeatureDefinition:功能定义,SPFarm对象有个FeatureDefinitions的属性,是功能定义的集合。PSite、SPWeb对象也有FeatureDefinitions属性,从SPFeature(功能)对象的FeatureDefinitionScope属性还能获取到一个SPFeatureDefinitionScope枚举值。

7、SPFeature:功能,SPWebApplication、SPSite、SPWeb都有一个Features属性,是它们的功能集合。在SharePoint页面的设置-〉系统设置-〉网站集管理-〉网站集功能 能看到网站集的功能;在SharePoint页面的设置-〉系统设置-〉网站操作-〉管理网站功能看到网站的功能。更多了功能请参考http://technet.microsoft.com/zh-cn/library/ff607883(v=office.14).aspx。

     接下来要准备写代码了,用Visual Studio 2012创建一个控制台应用程序,为项目添加新项-〉数据-〉XML文件,为这个文件取一个温暖的名字——这是部署信息的配置文件,我这里就叫DeploymentInfo.xml了。文件属性-〉高级-〉复制到输出目录选择“如果较新就复制”。然后加入类似下面的内容:

复制代码

<configuration><solution literalPath="WSPPackage\SharePointSolution1.wsp" webApplicationName="SharePoint - 80" isForceInstall="true" ><feature featureId="cc7c09d1-023c-4917-82ab-b82b846631a8" siteUrl="http://sharepointsiteurl/" webName="" isForceInstall="true" /><feature featureId="74f7c14b-dcca-4d4f-b2f7-7be3e7955bd1" siteUrl="http://sharepointsiteurl/" webName="" isForceInstall="true" /></solution><solution literalPath="WSPPackage\SharePointSolution2.wsp" webApplicationName="SharePoint - 80" isForceInstall="true" ><feature featureId="f60f8bfe-5d65-43de-86b4-cc10fbcab800" siteUrl="http://sharepointsiteurl/" webName="webName" isForceInstall="true" /><feature featureId="963241f7-b33e-4c3e-bf00-cbcaf1c22412" siteUrl="http://sharepointsiteurl/" webName="webName" isForceInstall="true" /><feature featureId="26dab42a-0f42-449b-84c0-111a8474dbc4" siteUrl="http://sharepointsiteurl/" webName="webName" isForceInstall="true" /></solution>
</configuration>

复制代码

     一个solution节点对应一个解决方案包,可以配置部署多个解决方案;一个feature节点对应一个功能,feature节点在solution节点下,也可以有N个。

     再解释下配置参数:literalPath是解决方案包的路径,我会在程序文件夹下再放个WSPPackage文件夹,发布生成的wsp文件就放在这里;featureId是功能的ID;webApplicationName是web应用程序的名称,siteUrl是网站集的URL,webName是网站的名称,这三个参数如果没有将遍历全部(根网站的webName是空字符串)。isForceInstall是是否强制参数,其实我们在Visual Studio里可以设置这个参数,但是默认是"False ",我不愿意改它。

     在Web部件代码Visual Studio解决方案管理器里选中项目-〉属性窗口可以看到解决方案的属性。

     

    双击Features文件夹下的某个Feature文件,在属性窗口就能看到功能的属性,包括功能ID。

     

      我们程序代码要做的事就是利用这些部署信息将开发元素的解决方案包添加部署,功能激活。

      下面正式要上C#代码了,进入代码文件Program.cs 的Main方法,先来段简单的配置文件遍历,取出解决方案和功能信息,要引用命名空间 System.Xml.Linq:

复制代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;namespace SharePointWspDeployApplication
{class Program{static void Main(string[] args){XElement root = XElement.Load("DeploymentInfo.xml");IEnumerable<XElement> solutionXElements = root.Elements("solution");foreach (XElement solutionXElement in solutionXElements){string literalPath = solutionXElement.Attribute("literalPath") != null ? solutionXElement.Attribute("literalPath").Value : null;XElement[] featureXElements = solutionXElement.Elements("feature").ToArray();foreach (var featureXElement in featureXElements){Guid featureId = new Guid(featureXElement.Attribute("featureId").Value);}}}}
}

复制代码

       这里解决方案添加只要为场对象添加就行,我直接调用SPFarm对象的SPSolutionCollection类型Solutions属性的Add方法,传给wsp文件的路径。(SPSite、SPWeb对象也有Solutions属性,但是SPUserSolutionCollection类型)。添加完成后我们可以到SharePoint配置数据库SharePoint_Config的Objects表里找到两条name是wsp文件名的记录(wsp文件名是小写的),有一条能够在 Binaries表中找到对应记录(Id和ObjectId关联),用下面的方法可以把wsp文件取出来。

复制代码

private static void GetFileFromConfigDataBase(string fileName,string path){byte[] file = null;const string connectionString = "data source=.;initial catalog=SharePoint_Config;Trusted_Connection=Yes;";const string commandText = "SELECT [FileImage] FROM [Objects] INNER JOIN [Binaries] ON [Objects].[Id] = [Binaries].[ObjectId] WHERE [name] = @fileName";using (SqlConnection sqlConnection = new SqlConnection(connectionString)){using (SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection)){sqlCommand.Parameters.Add(new SqlParameter("@fileName", fileName));sqlConnection.Open();using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader(CommandBehavior.SingleRow)){if (sqlDataReader.Read()){file = (byte[])sqlDataReader[0];}}}}if (file != null){using (FileStream fileStream = new FileStream(Path.Combine(path,fileName), FileMode.CreateNew)){fileStream.Write(file, 0, file.Length);fileStream.Close();}}}

复制代码

       文件取出来后,我们可以把这个wsp文件解压,和上传之前的对比下。我的电脑上的解压缩软件可以直接解压,如果不行可尝试把扩展名改成cab的。解压缩后可以看到文件夹里有manifest.xml文件、DLL文件、Feature文件夹。

      部署解决方案稍微复杂些,SPSolution对象有两个部署方法LocalDeploy和Deploy(Deploy要传个时间点启用Timer job,是多个Web前端服务器可用部署方式),每个部署方法又有个重载。

      在Visual Studio项目属性窗口有个程序集部署目标的属性,可选择GlobalAssemblyCache或WebApplication,如果沙盒解决方案选择“True”,这个属性就不能选了。那么我们直接用Visual Studio部署时如果选择了GlobalAssemblyCache会是什么样呢?我试着将一个Web部件项目属性的程序集部署目标设置为GlobalAssemblyCache,然后选择项目右键部署,再到SharePoint管理中心主页的管理场解决方案列表,发现Deployed To列是个URL而不是“Globally deployed.”!

      然后我在SharePoint 2013 Management Shell执行下面的命令部署(未指定Web应用程序):

1

Install-SPSolution -Identity VisualWebPartProject1.wsp  -GACDeployment –FullTrustBinDeployment

      执行后发现也报错!

     

     看来是我理解乱了。原来这个程序集部署目标的属性决定的是DLL的部署位置,如果我们选择GlobalAssemblyCache,将在盘符:\Windows\Microsoft.NET\assembly\GAC_MSIL\ 找到对应文件;选择WebApplication,则在盘符:\inetpub\wwwroot\wss\VirtualDirectories\80\bin\找到对应文件。SPSolution对象有个ContainsGlobalAssembly属性,程序集部署目标如果选择了GlobalAssemblyCache,它就是“true”。

     为了避免上述 “此解决方案包含Web应用程序范围的资源,必须将其部署到一个或多个Web应用程序。”的异常,可以通过SPSolution对象的ContainsWebApplicationResource属性来判断,如果为“True”,部署时要指定Web应用程序,即使用带Collection<SPWebApplication>参数的部署重载方法。

     解决方案的添加和部署操作代码要写在外层对解决方案信息节点遍历的foreach循环里。下面是我添加和部署解决方案的代码(要添加程序集-扩展-Microsoft.SharePoint引用,命名空间要引入Microsoft.SharePoint.Administration,如果系统是64位的,生成-目标平台也要改成x64):

    

复制代码

            XElement root = XElement.Load("DeploymentInfo.xml");IEnumerable<XElement> solutionXElements = root.Elements("solution");SPWebApplicationCollection spWebApplicationCollection = SPWebService.ContentService.WebApplications;foreach (XElement solutionXElement in solutionXElements){string literalPath = solutionXElement.Attribute("literalPath") != null ? solutionXElement.Attribute("literalPath").Value : null;XAttribute webApplicationNameAttribute = solutionXElement.Attribute("webApplicationName");SPWebApplication[] spWebApplications;if (webApplicationNameAttribute != null && !string.IsNullOrEmpty(webApplicationNameAttribute.Value)){spWebApplications = new[] { spWebApplicationCollection[webApplicationNameAttribute.Value] };}else{spWebApplications = spWebApplicationCollection.ToArray();}Console.WriteLine("开始添加解决方案:");string wspName = Path.GetFileName(literalPath).ToLower();SPSolution spSolution = SPFarm.Local.Solutions[wspName];if (spSolution != null){if (spSolution.Deployed){if (spSolution.ContainsWebApplicationResource){Console.WriteLine("正在从Web应用程序回收解决方案 “{0}”...", spSolution.Name);spSolution.RetractLocal(spSolution.DeployedWebApplications);}else{Console.WriteLine("正在回收解决方案 “{0}”...", spSolution.Name);spSolution.RetractLocal();}}Console.WriteLine("正在删除解决方案 “{0}”...", spSolution.Name);spSolution.Delete();}if (!string.IsNullOrEmpty(literalPath) && File.Exists(literalPath)){Console.WriteLine("正在添加解决方案 “{0}”...", wspName);spSolution = SPFarm.Local.Solutions.Add(literalPath);bool isForceInstall = false;if (solutionXElement.Attribute("isForceInstall") != null){isForceInstall = string.Equals("true", solutionXElement.Attribute("isForceInstall").Value, StringComparison.OrdinalIgnoreCase);}if (spSolution.ContainsWebApplicationResource){Console.WriteLine(@"正在部署解决方案 “{0}” 到 Web应用程序 “{1}”...", spSolution.Name, string.Join(",", spWebApplications.Select(a => a.DisplayName).ToArray()));spSolution.DeployLocal(spSolution.ContainsGlobalAssembly, new Collection<SPWebApplication>(spWebApplications), isForceInstall);}else{Console.WriteLine("正在部署解决方案 “{0}”...", spSolution.Name);spSolution.DeployLocal(spSolution.ContainsGlobalAssembly, isForceInstall);}}else{Console.WriteLine("literalPath为空或指定路径文件不存在!");}}

复制代码

      解决方案添加并部署后,可以到激活功能了。我们在开发时设置的功能属性可以通过SPFeatureDefinition的对象得到(这个SPFeatureDefinition对象可以用SPFarm对象的FeatureDefinitions属性以功能ID或名称作索引获取)。例如始终强制安装,应该对应SPFeatureDefinition对象的AlwaysForceInstall属性;ActivationDependencies属性应该对应功能激活依赖项集合。还有个默认激活(Activate On Default)的属性,我本以为就是SPFeatureDefinition对象的ActivateOnDefault属性,但是在属性窗口改了一下发现竟然没效果!后来我在功能清单的XML里找到了个ActivateOnDefault="true"描述。一般的情况下,您修改功能的属性后,这个manifest.xml里的内容要跟着变的,但是这个默认激活属性在我当前的Visual Studio版本怎么设置都没反应。不过您如果在下面的编辑选项里强制更改ActivateOnDefault="false"还是有效果的。

       功能有个重要的范围属性——SPFeatureDefinition对象的Scope,可选择Farm、WebApplication、Site或Web,在代码里这是个SPFeatureScope枚举。我的Web部件如果选择的不是Site,在发布的时候会报类似“错误 1 无法通过具有 WebApplication 范围的功能部署项目项‘VisualWebPart1’。”的错误。因为SPWebApplication、SPSite、SPWeb对象都有一个Features的属性,我们只要根据范围调用SPFeatureCollection的Add方法添加就可以了。下面是添加功能的代码(Farm和WebApplication范围的功能我还没有实际使用和验证过,抱歉!):

复制代码

Console.WriteLine("开始激活功能:");foreach (var featureXElement in featureXElements){Guid featureId = new Guid(featureXElement.Attribute("featureId").Value);SPFeatureDefinition definition =SPFarm.Local.FeatureDefinitions[featureId];if (definition != null){if (definition.ActivateOnDefault){bool isForceInstall = definition.AlwaysForceInstall;if (featureXElement.Attribute("isForceInstall") != null){isForceInstall = string.Equals("true", featureXElement.Attribute("isForceInstall").Value, StringComparison.OrdinalIgnoreCase);}if (definition.Scope == SPFeatureScope.Site){XAttribute siteUrlAttribute = featureXElement.Attribute("siteUrl");if (siteUrlAttribute != null && !string.IsNullOrEmpty(siteUrlAttribute.Value)){using (SPSite spSite = new SPSite(siteUrlAttribute.Value)){Console.WriteLine("正在激活功能“{0}”到网站集 “{1}”...", definition.DisplayName, spSite.Url);spSite.Features.Add(featureId, isForceInstall);}}else{foreach (SPSite spSite in spWebApplications.SelectMany(a => a.Sites)){Console.WriteLine("正在激活功能“{0}”到网站集“{1}”...", definition.DisplayName, spSite.Url);spSite.Features.Add(featureId, isForceInstall);}}}else if (definition.Scope == SPFeatureScope.Web){XAttribute siteUrlAttribute = featureXElement.Attribute("siteUrl");XAttribute webNameAttribute = featureXElement.Attribute("webName");if (siteUrlAttribute != null){using (SPSite spSite = new SPSite(siteUrlAttribute.Value)){if (webNameAttribute != null){using (SPWeb spWeb = spSite.AllWebs[webNameAttribute.Value]){Console.WriteLine("正在激活功能“{0}”到网站“{1}”...", definition.DisplayName, spWeb.Title);spWeb.Features.Add(featureId, isForceInstall);}}else{foreach (SPWeb spWeb in spSite.AllWebs){using (spWeb){Console.WriteLine("正在激活功能 “{0}”到 网站“{1}”...", definition.DisplayName, spWeb.Title);spWeb.Features.Add(featureId, isForceInstall);}}}}}else{foreach (SPWeb spWeb in spWebApplications.SelectMany(a => a.Sites.SelectMany(s => s.AllWebs))){Console.WriteLine("正在激活功能“{0}”到 网站“{1}”...", definition.DisplayName, spWeb.Title);spWeb.Features.Add(featureId, isForceInstall);}}}else if (definition.Scope == SPFeatureScope.WebApplication){foreach (SPWebApplication spWebApplication in spWebApplications){Console.WriteLine("正在激活功能“{0}”到 Web应用程序 “{1}”...", definition.DisplayName, spWebApplication.DisplayName);spWebApplication.Features.Add(featureId, isForceInstall);}}else if (definition.Scope == SPFeatureScope.Farm){//TODO:还未找到方案}else{//TODO:还未找到方案}}else{Console.WriteLine("ID为{0}的功能默认不在安装期间激活!", featureId.ToString());}}else{Console.WriteLine("未找到ID为{0}的功能定义!", featureId.ToString());}}

复制代码

      功能成功被添加后,在盘符:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\TEMPLATE\FEATURES下找到了对应的功能文件夹,这个路径可以通过SPFeatureDefinition对象的属性获取。

     下面是删除功能和功能定义的代码:

复制代码

Console.WriteLine("开始回收功能:");foreach (var featureXElement in featureXElements){Guid featureId = new Guid(featureXElement.Attribute("featureId").Value);SPFeatureDefinition definition =SPFarm.Local.FeatureDefinitions[featureId];if (definition != null){bool isForceInstall = definition.AlwaysForceInstall;if (featureXElement.Attribute("isForceInstall") != null){isForceInstall = string.Equals("true", featureXElement.Attribute("isForceInstall").Value, StringComparison.OrdinalIgnoreCase);}if (definition.Scope == SPFeatureScope.Site){XAttribute siteUrlAttribute = featureXElement.Attribute("siteUrl");if (siteUrlAttribute != null && !string.IsNullOrEmpty(siteUrlAttribute.Value)){using (SPSite spSite = new SPSite(siteUrlAttribute.Value)){Console.WriteLine("正在从网站集“{0}”回收功能“{1}”...", spSite.Url, definition.DisplayName);SPFeature spFeature = spSite.Features[featureId];if (spFeature != null){spSite.Features.Remove(featureId, isForceInstall);}}}else{foreach (SPSite spSite in spWebApplications.SelectMany(a => a.Sites)){Console.WriteLine("正在从网站集“{0}”回收功能“{1}”...", spSite.Url, definition.DisplayName);SPFeature spFeature = spSite.Features[featureId];if (spFeature != null){spSite.Features.Remove(featureId, isForceInstall);}}}}else if (definition.Scope == SPFeatureScope.Web){XAttribute siteUrlAttribute = featureXElement.Attribute("siteUrl");XAttribute webNameAttribute = featureXElement.Attribute("webName");if (siteUrlAttribute != null){using (SPSite spSite = new SPSite(siteUrlAttribute.Value)){if (webNameAttribute != null){using (SPWeb spWeb = spSite.AllWebs[webNameAttribute.Value]){Console.WriteLine("正在从网站“{0}”回收功能“{1}”...", spWeb.Title, definition.DisplayName);SPFeature spFeature = spWeb.Features[featureId];if (spFeature != null){spWeb.Features.Remove(featureId, isForceInstall);}}}else{foreach (SPWeb spWeb in spSite.AllWebs){using (spWeb){Console.WriteLine("正在从网站“{0}”回收功能“{1}”...", spWeb.Title, definition.DisplayName);SPFeature spFeature = spWeb.Features[featureId];if (spFeature != null){spWeb.Features.Remove(featureId, isForceInstall);}}}}}}else{foreach (SPWeb spWeb in spWebApplications.SelectMany(a => a.Sites.SelectMany(s => s.AllWebs))){Console.WriteLine("正在从网站“{0}”回收功能“{1}”...", spWeb.Title, definition.DisplayName);SPFeature spFeature = spWeb.Features[featureId];if (spFeature != null){spWeb.Features.Remove(featureId, isForceInstall);}}}}else if (definition.Scope == SPFeatureScope.WebApplication){foreach (SPWebApplication spWebApplication in spWebApplications){Console.WriteLine("正在从Web应用程序“{0}”回收功能“{1}” ...", spWebApplication.DisplayName, definition.DisplayName);SPFeature spFeature = spWebApplication.Features[featureId];if (spFeature != null){spWebApplication.Features.Remove(featureId, isForceInstall);}}}else if (definition.Scope == SPFeatureScope.Farm){//TODO:还未找到方案}else{//TODO:还未找到方案}Console.WriteLine("正在删除功能定义“{0}”...", definition.DisplayName);string featurePath = definition.RootDirectory;definition.Delete();  }}

复制代码

      遗憾的是,上面的代码不能够完美解决部署冲突的问题。例如部署过Web部件后我又修改了.webpart文件里的Title,用这种方式重新部署之后不会马上体现更改,而Visual Studio的部署功能却有这个能力——在输出窗口能看到“已找到 1 个部署冲突。正在解决冲突..    已从服务器中删除文件“.../_catalogs/wp/VisualWebPartProject1_VisualWebPart1.webpart”。”的信息。现在需要个很笨的方法——先到网站设置->Web设计器库->Web部件库把对应的Web部件删掉。

      现在一个简单的SharePoint开发包部署程序就给大家介绍完了。不过这个程序还有很多的不足,例如: 我只用它部署过列表、Web部件和事件接收器,不能支持用户解决方案(SPUserSolution),不能部署网站模板;部署的环境只是针对一个Web前端服务器的本地部署,需要使用SharePoint管理员权限运行;另外对部署冲突和功能依赖项的处理还没有找到比较满意的办法。我会继续研究总结并和大家分享。最后,还希望各位高手专家看过此文能够不惜赐教,多多指点!

SharePoint开发包部署程序下载地址:

http://files.cnblogs.com/CSharpDevelopers/SharePointWspDeployApplication.zip

参考资料:

http://technet.microsoft.com/zh-cn/library/cc263205(v=office.15).aspx

http://msdn.microsoft.com/zh-cn/library/microsoft.sharepoint.administration(v=office.12).aspx

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CCNP-第三篇 EIGRP高级版(四个特性)(下)+OSPF复习

CCNP-第三篇 EIGRP高级版(四个特性)(下)OSPF复习 EIGRP篇到此完结 接下来四篇都是OSPF哦 EIGRP下发默认路由 来看一个环境 这种环境一般来说是很常见的,然后这个呢,下面的服务器,都是需要指向汇聚层的,那么如果环境很大的时候,每个机器都要手动写,就很麻烦了 >可以做一个…

CCNP-第四篇-OSPF高级版(一)

CCNP-第四篇-OSPF高级版(一) OSPFOpen shortes path first 开放式最短路径优先协议 最大优点:公有,开放,任何一个品牌都能用 EIGRP最大优点:快的一批 EIGRP最大缺点:思科私有 OSPF甚至于在Liunx上也能运行起来 OSPF是采用动态更新的 所以会给设备带来大量的硬件消耗 在OSPF中…

【转】DevOps到底是什么意思?

提到DevOps这个词&#xff0c;我相信很多人一定不会陌生。 作为一个热门的概念&#xff0c;DevOps近年来频频出现在各大技术社区和媒体的文章中&#xff0c;备受行业大咖的追捧&#xff0c;也吸引了很多吃瓜群众的围观。 那么&#xff0c;DevOps是什么呢&#xff1f; 有人说它…

CCNP-第五篇-OSPF高级版(二)

CCNP-第五篇-OSPF高级版(二) 链路状态数据库LSDB拓扑表 link state database 收到之后放入自己的数据库再计算最新的放入路由表 根据COST值来计算 >COST值的计算方式10的8次方除以带宽这个环境会涉及一个东西叫做重分布,这类会做,然后下一章或者下下章会详细开始讲. 详细环…

IIS 内部运行机制

ASP.NET是一个非常强大的构建Web应用的平台&#xff0c;它提供了极大的灵活性和能力以致于可以用它来构建所有类型的Web应用。 绝大多数的人只熟悉高层的框架如&#xff1a; WebForms 和 WebServices — 这些都在ASP.NET层次结构的最高层。 这篇文章的资料收集整理自各种微软公…

CCNP-第六篇-OSPF高级版(三)

CCNP-第六篇-OSPF高级版(三) 这一节差不多都是密码认证了,还有个NSSA和OE1,OE2 OSPF默认路由OSPF认证问题OSPF特殊区域,NSSA,STUB OSPF下发默认路由 其实跟EIGRP一样,只不过是下发一条路由给别人指向自己 一般都用于核心连接出口处,或者汇聚连接核心处 如果是这种环境下,那…

SharePoint 2013异常信息的查看

刚刚学习SharePoint开发的时候&#xff0c;经常遇到一些异常&#xff0c;却不能直接看到详细信息&#xff0c;很郁闷。这里做下简单的整理&#xff0c;方便查找&#xff1a; 1、代码未处理异常出现黄页——”‘/’应用程序中的服务器错误。运行时错误“。 其实这个黄页是ASP.N…

CCNP-第七篇-OSPF高级版(四)+策略开头

CCNP-第七篇-OSPF高级版(四)策略开头 今天讲NSSA和完全NSSA NSSA区域叫做非完全末节区域,这个东西都不知道命名的人怎么想的 因为完全NSSA区域叫做完全非完全末节区域,pleas,你人傻了吗? NSSA区域特点:过滤4,5类的LSA,同时会5类转为7类条目 7类在路由表里面是ON的 然后,7类除…

同步界面

设置FFS程序 当你下载、安装好后桌面会出现这两个图标。左边是主要的程序&#xff0c;右边软件用来设置自动同步。打开绿色图标的程序。 打开蓝色的设置按钮。 建议选择“文件时间和大小”。单纯的大小不能反映内容。比较文件内容又取决于硬盘速度。如果速度够快可以选择文件内…

CCNP-第八篇-分发列表+PRB+重分布+Route-Map

CCNP-第八篇-分发列表PRB重分布Route-Map 这个学不好,BGP就一定学不好 Route-Map 这样理解吧,在Route-map中 ACL就相当于警察,只能抓,不能判 Rroute-map呢就相当于法官,法官可以判罚 一般都是结合使用的,因为不结合这玩意也没法用环境如图 需求:干掉100.1.1.0/24 在Route-m…

虎年第一篇-CCNP-第九篇-BGP(一)

CCNP-第九篇-BGP(一) 首先,开工啦,祝大家2022新年快乐虎年大吉,虎虎生威哦BGP是一个网络工程师的分水岭 这是真的,BGP一般很大的企业才能用得上,或者ISP运营商 人家可以不用,但是你不能不会吧, BGP,CCIE必考 BGP有四节课基础,后面CCIE的部分还有 从BGP开始就要换一种理念 因为之…

rsync算法原理及使用

如果服务器之间需要保持某些文件的一致&#xff0c;我们可以使用scp来复制&#xff0c;如果需要长期保持一致&#xff0c;可以配合crontab脚本来使用。但是此时我们有更优的方式&#xff0c;就是rsynccrontab来实现定时增量传输保持文件一致。 rsync功能很强大&#xff0c;网上…

CCNP-第十篇-BGP(二)

CCNP-第十篇-BGP(二) 首先 BGP都基本上部署在PE,CE设备 PE:Provider edge 运营商边界 CE:Customer edge 用户边界 建立BGP 1.一般呢,是会使用环回口建立BGP 2.因为他是虚拟接口,很稳定,而且不会down,只要系统在,他就不会down;; 3.如果他down了就是整个网络都断了 4.节约接口使…

CCNP-第十一篇-BGP(三)(精髓篇)

CCNP-第十一篇-BGP(三) BGP十三条线路原则(大点) 能修改的前7条,後6条是无法修改的,所以实际上7条 跟ACL一样,从上往下执行,比如第一条比较出来了就不会继续往下了 工作中比较多用的,第四条根据as-path一,权重-Weight 1.思科里面叫权重,是思科私有的,在华为叫首选优先级(Pre…

WSS 数据库表中的 UserInfo 表中的 tp_SystemId 字段的使用

在 WSS 的数据库中&#xff0c;UserInfo表的 tp_SystemId 记录的是用户登录验证时需要用到的数据&#xff0c;是此用户在 AD( Active Directory ) 中的 SID( Security ID )。此字段的数据很重要&#xff0c;不小心改动的话&#xff0c;此用户将不能登录 WSS。 这里介绍一下如何…

CCNP-第十二篇-BGP(四)

CCNP-第十二篇-BGP(四) 这次接着上次的选路原则继续干 上次是前6条,现在是跟后面的7条 BGP的选路原则默认是11条,最大可以配置后去到13条七.EBGP路由优于IBGP 这个不知道咋讲呢 如果A-B-C 那么A-B为IBGP B-C为EBGP的话 他们同时宣告一个条目 在两边对称的情况下,会选择EBGP宣告…

使用Module自定义网站定义(Site Definition)

在WSS SDK中有一篇文章介绍了使用Modules添加文件到网站定义中(可以在http://msdn.microsoft.com中搜索Using Modules to Add Files to a Site Difinition找到)&#xff0c;不过很多东西只是稍微提了一下&#xff0c;具体怎么操作并没有讲到。 一般的&#xff0c;我们可以用下…

CCNP-第十三篇-BGP(五)

CCNP-第十三篇-BGP(五) 这一节要讲下BGP联邦 干啥用的呢? 打破IBGP的传递问题 其实这个东东有点像BGP版本的NAT 啥意思呢? 我自己启动AS100 但是对外宣告200 通过EBGP打破IBGP的传递问题总有AS:1-65535 私有AS 65412-65535 网络环境 环境搭建好之后,R2和R3互为ibgp,as为65…

CCNP-第十五篇-VXLAN(一)

CCNP-第十五篇-VXLAN(一) 到了这个阶段呢,怎么说呢,简单的NP级别的交换我都跳过去了,但是后期会补, 所以这个衔接可能新手或者不会的看的有的迷茫 但是出自个人原因只好这么干了,VXLAN3篇差不多就到IE的MPLS,各种VPN 然后为什么先发第十六不发十五呢 十五是BGP的综合实验,暂时…

CCNP-第十六篇-VXLAN效果演示+端口镜像

CCNP-第十六篇-VXLAN(二)端口镜像 这一篇主要搞vxlan的实操演示 VXLAN演示 正常的ensp里面应该是没这个镜像的 要用到这个CE12800 我这有,可以提供给大家使用 链接&#xff1a;https://pan.baidu.com/s/1nqGo8a7mmWpthu-CuBC80Q?pwdcjnb 提取码&#xff1a;cjnb 这玩意要手动…