1,在Web上修改指定文件位置的Web.config
这里需要使用 WebConfigurationManager 类,但必须使用WebConfigurationFileMap类来指定文件位置,看代码:
long appId = 123; //修改网站的配置文件 var configFile = new FileInfo(configFilePath); var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name); var wcfm = new WebConfigurationFileMap(); wcfm.VirtualDirectories.Add("/", vdm); var config = WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/", siteName); AppSettingsSection appSection = (AppSettingsSection)config.GetSection("appSettings"); appSection.Settings["abc"].Value = "system tag"; appSection.Settings["appId"].Value = appId.ToString(); config.Save();
上面的代码参考自 stackoverflow ,但是OpenMappedWebConfiguration 必须指定第3个参数,否则会报错。不过,siteName 并不要求与IIS的站点名字对应,随意写一个也可以。
2,使用angularJS 绑定站点信息
首先定义一个 webSiteListApp HTML代码片断:
<div ng-app="webSiteListApp" class="container"> <div ng-controller="webSiteListController"> <ul> <li ng-repeat="item in siteList"> 站点名:{{item.SiteName}} ------绑定信息:{{item.DomainPort}} </li> </ul> </div> </div>
然后定义module和service:
<script type="text/javascript"> // 参考 http://www.infragistics.com/community/blogs/dhananjay_kumar/archive/2015/05/13/how-to-use-angularjs-in-asp-net-mvc-and-entity-framework-4.aspx var webSiteListApp = angular.module("webSiteListApp", []); webSiteListApp.controller("webSiteListController", function ($scope, webSiteService) { getSiteList(); function getSiteList() { var list = webSiteService.getSiteList() .success(function (sites) { $scope.siteList = sites; console.log($scope.siteList); }) .error(function (error) { $scope.status = 'Unable to load customer data: ' + error.message; console.log($scope.status); }); } }); webSiteListApp.factory("webSiteService", ["$http", function ($http) { var webSiteService = {}; webSiteService.getSiteList = function () { return $http.get("/SiteManage/GetServerBindings"); } return webSiteService; }]); </script>
这里定义了一个叫做 webSiteListApp 的module,然后注册一个 webSiteListController 的控制器,该控制器在前面的HTMl代码中定义,最后创建一个 webSiteService ,它监听后来MVC来的数据,该数据对应的ASP.NET MVC 方法如下:
public JsonResult GetServerBindings() { var siteList = IISControlHelper.IISWorker.GetServerBindings(); return Json(siteList, JsonRequestBehavior.AllowGet); }
3,IIS管理程序
可以创建,删除网站,添加应用程序池,代码如下:
using System; using System.Collections; using System.Collections.Generic; using System.DirectoryServices; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace IISControlHelper { /// <summary> /// IIS 操作方法集合 /// http://blog.csdn.net/ts1030746080/article/details/8741399 错误 /// </summary> public class IISWorker { private static string HostName = "localhost"; /// <summary> /// 获取本地IIS版本 /// </summary> /// <returns></returns> public static string GetIIsVersion() { try { DirectoryEntry entry = new DirectoryEntry("IIS://" + HostName + "/W3SVC/INFO"); string version = entry.Properties["MajorIISVersionNumber"].Value.ToString(); return version; } catch (Exception se) { //说明一点:IIS5.0中没有(int)entry.Properties["MajorIISVersionNumber"].Value;属性,将抛出异常 证明版本为 5.0 return string.Empty; } } /// <summary> /// 创建虚拟目录网站 /// </summary> /// <param name="webSiteName">网站名称</param> /// <param name="physicalPath">物理路径</param> /// <param name="domainPort">站点+端口,如192.168.1.23:90</param> /// <param name="isCreateAppPool">是否创建新的应用程序池</param> /// <returns></returns> public static int CreateWebSite(string webSiteName, string physicalPath, string domainPort,bool isCreateAppPool) { DirectoryEntry root = new DirectoryEntry("IIS://" + HostName + "/W3SVC"); // 为新WEB站点查找一个未使用的ID int siteID = 1; foreach (DirectoryEntry e in root.Children) { if (e.SchemaClassName == "IIsWebServer") { int ID = Convert.ToInt32(e.Name); if (ID >= siteID) { siteID = ID + 1; } } } // 创建WEB站点 DirectoryEntry site = (DirectoryEntry)root.Invoke("Create", "IIsWebServer", siteID); site.Invoke("Put", "ServerComment", webSiteName); site.Invoke("Put", "KeyType", "IIsWebServer"); site.Invoke("Put", "ServerBindings", domainPort ); site.Invoke("Put", "ServerState", 2); site.Invoke("Put", "FrontPageWeb", 1); site.Invoke("Put", "DefaultDoc", "Default.html"); // site.Invoke("Put", "SecureBindings", ":443:"); site.Invoke("Put", "ServerAutoStart", 1); site.Invoke("Put", "ServerSize", 1); site.Invoke("SetInfo"); // 创建应用程序虚拟目录 DirectoryEntry siteVDir = site.Children.Add("Root", "IISWebVirtualDir"); siteVDir.Properties["AppIsolated"][0] = 2; siteVDir.Properties["Path"][0] = physicalPath; siteVDir.Properties["AccessFlags"][0] = 513; siteVDir.Properties["FrontPageWeb"][0] = 1; siteVDir.Properties["AppRoot"][0] = "LM/W3SVC/" + siteID + "/Root"; siteVDir.Properties["AppFriendlyName"][0] = "Root"; if (isCreateAppPool) { DirectoryEntry apppools = new DirectoryEntry("IIS://" + HostName + "/W3SVC/AppPools"); DirectoryEntry newpool = apppools.Children.Add(webSiteName, "IIsApplicationPool"); newpool.Properties["AppPoolIdentityType"][0] = "4"; //4 newpool.Properties["ManagedPipelineMode"][0] = "0"; //0:集成模式 1:经典模式 newpool.Properties["ManagedRuntimeVersion"][0] = "v4.0"; newpool.CommitChanges(); siteVDir.Properties["AppPoolId"][0] = webSiteName; } siteVDir.CommitChanges(); site.CommitChanges(); return siteID; } /// <summary> /// 得到网站的物理路径 /// </summary> /// <param name="rootEntry">网站节点</param> /// <returns></returns> public static string GetWebsitePhysicalPath(DirectoryEntry rootEntry) { string physicalPath = ""; foreach (DirectoryEntry childEntry in rootEntry.Children) { if ((childEntry.SchemaClassName == "IIsWebVirtualDir") && (childEntry.Name.ToLower() == "root")) { if (childEntry.Properties["Path"].Value != null) { physicalPath = childEntry.Properties["Path"].Value.ToString(); } else { physicalPath = ""; } } } return physicalPath; } /// <summary> /// 获取站点名 /// </summary> public static List<IISInfo> GetServerBindings() { List<IISInfo> iisList = new List<IISInfo>(); string entPath = String.Format("IIS://{0}/w3svc", HostName); DirectoryEntry ent = new DirectoryEntry(entPath); foreach (DirectoryEntry child in ent.Children) { if (child.SchemaClassName.Equals("IIsWebServer", StringComparison.OrdinalIgnoreCase)) { if (child.Properties["ServerBindings"].Value != null) { object objectArr = child.Properties["ServerBindings"].Value; string serverBindingStr = string.Empty; if (IsArray(objectArr))//如果有多个绑定站点时 { object[] objectToArr = (object[])objectArr; serverBindingStr = objectToArr[0].ToString(); } else//只有一个绑定站点 { serverBindingStr = child.Properties["ServerBindings"].Value.ToString(); } IISInfo iisInfo = new IISInfo(); iisInfo.DomainPort = serverBindingStr; iisInfo.AppPool = child.Properties["AppPoolId"].Value.ToString();//应用程序池,有可能不准确 object objComment=child.Properties["ServerComment"].Value; if (objComment != null) { iisInfo.SiteName = objComment.ToString(); } iisList.Add(iisInfo); } } } return iisList; } public static bool CreateAppPool(string appPoolName, string Username, string Password) { bool issucess = false; try { //创建一个新程序池 DirectoryEntry newpool; DirectoryEntry apppools = new DirectoryEntry("IIS://" + HostName + "/W3SVC/AppPools"); newpool = apppools.Children.Add(appPoolName, "IIsApplicationPool"); //设置属性 访问用户名和密码 一般采取默认方式 newpool.Properties["WAMUserName"][0] = Username; newpool.Properties["WAMUserPass"][0] = Password; newpool.Properties["AppPoolIdentityType"][0] = "3"; newpool.CommitChanges(); issucess = true; return issucess; } catch // (Exception ex) { return false; } } /// <summary> /// 建立程序池后关联相应应用程序及虚拟目录 /// </summary> public static void SetAppToPool(string appname,string poolName) { //获取目录 DirectoryEntry getdir = new DirectoryEntry("IIS://localhost/W3SVC"); foreach (DirectoryEntry getentity in getdir.Children) { if (getentity.SchemaClassName.Equals("IIsWebServer")) { //设置应用程序程序池 先获得应用程序 在设定应用程序程序池 //第一次测试根目录 foreach (DirectoryEntry getchild in getentity.Children) { if (getchild.SchemaClassName.Equals("IIsWebVirtualDir")) { //找到指定的虚拟目录. foreach (DirectoryEntry getsite in getchild.Children) { if (getsite.Name.Equals(appname)) { //【测试成功通过】 getsite.Properties["AppPoolId"].Value = poolName; getsite.CommitChanges(); } } } } } } } /// <summary> /// 判断object对象是否为数组 /// </summary> public static bool IsArray(object o) { return o is Array; } } public class IISInfo { public string SiteName { get; set; } public string DomainPort { get; set; } public string AppPool { get; set; } } }
然后,写一个页面来创建网站:
前端HTML:
<form action="/SiteManage/CreateWebSite"> <fieldset>网站名称(不能重复):————<input type="text" name="siteName" class="myInput" /> </fieldset> <fieldset>网站基准目录(服务器):———<input type="text" name="physicalPath" class="myInput" /></fieldset> <fieldset>绑定域名(不能重复):————<input type="text" name="domain" class="myInput" /></fieldset> <fieldset>网站压缩文件路径(服务器):—<input type="text" name="zipFile" class="myInput" value="@ViewBag.ZipFile" /> 如果服务器没有网站压缩文件,请先上传。</fieldset> <input type="submit" name="submit1" value="提交" /> </form>
后端Controller:
public ActionResult CreateWebSite(string siteName, string physicalPath, string domain, string zipFile) { bool hasErr = false; string message = ""; string webSiteFolder = ""; //检查参数,physicalPath 允许不存在,之后解压缩文件的时候将自动创建 if (string.IsNullOrEmpty(siteName) || string.IsNullOrEmpty(physicalPath) || string.IsNullOrEmpty(domain) || string.IsNullOrEmpty(zipFile)) { hasErr = true; message = "参数不能为空!"; } //检查是否已经包含了要绑定的域名,如果是,则不允许创建 if (!hasErr) { var list = IISControlHelper.IISWorker.GetServerBindings(); foreach (var item in list) { if (string.Compare(item.DomainPort, domain, StringComparison.OrdinalIgnoreCase) > 0) { hasErr = true; message = domain + " 域名已经绑定过,不能创建绑定此域名的新站点。"; break; } } } //检查网站目录并解压缩文件到网站目录 if (!hasErr) { try { webSiteFolder = CheckWebSiteFolder(physicalPath, zipFile); if (System.IO.File.Exists(zipFile)) { UnZipFile(zipFile, physicalPath); } else { message = zipFile+" 文件不存在!"; hasErr = true; } } catch (Exception ex1) { message = ex1.Message; hasErr = true; } } if (!hasErr) { try { //创建网站 int siteNumber; siteNumber = IISControlHelper.IISWorker.CreateWebSite(siteName, webSiteFolder, "*:80:" + domain, true); message = siteNumber > 0 ? "成功" : "失败"; } catch (System.Runtime.InteropServices.COMException exCom) { hasErr = true; if (exCom.HResult == -2147024713) { message = "网站名已经存在!";//(应用程序池IIS进程)文件已经存在,上面的方法默认会创建跟网站同名的应用程序池名称 } else { message = exCom.Message; } } catch (Exception ex2) { hasErr = true; message = ex2.Message; } } ViewBag.SiteName = siteName; ViewBag.PhysicalPath = webSiteFolder; ViewBag.Domain = domain; ViewBag.ResultDesc = message; return View("CreateResult"); }
注意这里会创建一个跟站点名字同名的应用程序池,默认是.NET 4.0,创建后即启动站点。
相关代码下载,点击这里。
4,ASP.NET MVC 上传文件
前端HTML:
<form action="/SiteManage/Upload" method="post" enctype="multipart/form-data"> 上传网站压缩文件:<input type="file" name="file1" value="" style="300px;" class="myInput" /> <input type="submit" name="submit2" value="上传" /> <span>@ViewBag.Message </span> </form>
后端Controller:
public ActionResult Upload() { string message = ""; HttpPostedFileBase file = Request.Files["file1"]; if (System.IO.Path.GetExtension(file.FileName).ToLower() != ".zip") { message = "只能上传ZIP格式的压缩文件。"; return RedirectToAction("Index", new { zipFile = "", message }); } else { string filePath = System.IO.Path.Combine(HttpContext.Server.MapPath("../Uploads"), System.IO.Path.GetFileName(file.FileName)); file.SaveAs(filePath); message = "上传成功"; return RedirectToAction("Index", new { zipFile= filePath,message}); } }
注意Request.Files["file1"] 表示获取前端HTML页面的文件双传控件名字 file1 对应的文件。
5,.NET解压缩文件
.NET 4.5之后,集成了文件解压缩功能,下面是使用方法:
/// <summary> /// 解压缩文件到指定目录,将在指定目录下解压出一个压缩文件名字的最终的目录 /// </summary> /// <param name="ZipPath">ZIP文件路径</param> /// <param name="ExtractPath">要解压缩的目录</param> private void UnZipFile(string ZipPath,string ExtractPath) { //string NewFile = @"c:usersexampleuserNewFile.txt"; if (System.IO.File.Exists(ZipPath)) { using (ZipArchive Archive = ZipFile.Open(ZipPath, ZipArchiveMode.Update)) { //Archive.CreateEntryFromFile(NewFile, "NewEntry.txt"); //如果目录下面有文件,将解压缩失败,所以之前先备份目录 Archive.ExtractToDirectory(ExtractPath); } } }
注意这里支持ZIP格式,不是RAR格式,同时需要使用 using System.IO.Compression;相关的程序集。
6,备份文件夹
如果需要备份文件夹,可以使用Move 方法实现,看代码:
/// <summary> /// 检查站点目录,如果原来的目录已经存在,将自动备份,如果该目录不存在,将自动创建 /// </summary> /// <param name="physicalPath"></param> /// <param name="zipFile"></param> /// <returns></returns> private string CheckWebSiteFolder(string physicalPath, string zipFile) { string webSiteFolder = System.IO.Path.Combine(physicalPath, System.IO.Path.GetFileNameWithoutExtension(zipFile)); if (System.IO.Directory.Exists(webSiteFolder)) { System.IO.Directory.Move(webSiteFolder, webSiteFolder + "_back" + DateTime.Now.ToString("yyyyMMddHHmmss")); } //此目录 return webSiteFolder;
7,给MVC页面传递数据
可以使用ViewBag 方式,例如下面的方式:
public ActionResult Index(string zipFile="",string message="") { string iisVersion = IISControlHelper.IISWorker.GetIIsVersion(); ViewBag.IISVerion = iisVersion; ViewBag.ZipFile = zipFile; ViewBag.Message = message; return View(); }
ViewBag 是动态类型,在前端页面直接使用它既可。
也可以通过Action传递一个对象给页面,方法如下:
public ActionResult Index(string zipFile="",string message="") { var siteList = IISControlHelper.IISWorker.GetServerBindings(); return View(siteList); }
然后,在 index.cshtml 页面的头部,引入这个Model:
@model List<IISControlHelper.IISInfo> @{ ViewBag.Title = "ASP.NET在线创建网站Demo"; }
8,SQL语句创建Access数据库表
可以使用SqlServer的基本建表语句,但是有几点不同,首先,不能使用User这样的关键词,然后,在创建自增字段上与SqlServer不同。
Access需要采用下面的方式:
[User ID] autoincrement PRIMARY KEY
不能使用下面的方式:
[User ID] Integer PRIMARY KEY autoincrement
PRIMARY KEY语句必须放在 autoincrement 之后,否则语法错。可见,Access功能的确很简单。
完整的一个建立表语句:
CREATE TABLE [Users]( [User ID] autoincrement PRIMARY KEY ,[First Name] text ,[Last Name] text ,[Age] Integer )
PDF.NET SOD Ver5.3.3.0724 发布,增加了Access Code First 支持,可以生成上面的建表语句。
9,VS复制项目生成的文件到另外一个项目运行目录下
这个问题常见于DLL需要动态加载的情况下,该DLL是在另外一个项目下生成,主体项目运行前需要拷贝到当前运行目录下。
如果DLL的源码经常修改,手工复制比较费事情,采用项目的
生成时间--〉后期生成命令行,输入下面类似的命令:
XCOPY "$(TargetPath)" "$(ProjectDir)..MainExeProjin$(ConfigurationName)" /Y /D /R
这个命令会将当前项目生成的DLL复制到 跟当前项目文件夹同级的MainExeProjin文件夹下面去,$(ConfigurationName) 通常表示 Debug,Release.
10,使用XCopy备份指定日期之后的资料
使用下面的命令:
xcopy C:SourceDoc D:CopyedDoc /i /s /y /EXCLUDE:D:CopyedDocexcludeFile.txt /d:7-1-2010
这将备份 SourceDoc 目录下面的 7月1日之后所有的文件和文件夹,exclued 文件包含了要排除的文件,比如:
obj
bin
.jpeg
.png
.gif
11,使用jQuery为表格动态添加行
在表格中定义一个模板行,将它作为第一行,然后使用jQuery动态添加行:
<table id="TableID" style="100%;background: green;"> <thead> <th>测试</th> <th>测试</th> </thead> <tbody id="list_data" class="list-data"> <tr id=""> <td><input type="text" value="Test"></td> <td><input type="text" value="Test"></td> </tr> </tbody> </table>
然后使用如下JS代码实现:
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script> <script src="scripts/myplus.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#AddRow").click(function(){ AddRow(); }); }); function AddRow(){ var row = $("#list_data tr").eq(0).clone(); row.appendTo("#list_data"); } </script>
关键代码在于 tr节点的克隆。
12,搜索当前目录的子目录或者上级目录下的子目录中特定的目录
首先,搜索当前目录下的子目录,如果没有,逐层搜索上级目录下面的所有子目录,有没有特定的目录。为了防止其它子目录可能跟目标目录重名,还可以同时指定目标目录下特定的一级子目录或者文件。这也是一个“深度优先搜索”的例子。下面是完整的代码:
/// <summary> /// 搜索特定的目录 /// </summary> public class SearchSpecFolder { /// <summary> /// 当前搜索总次数 /// </summary> public int SerachCount { get; private set; } /// <summary> /// 搜索指定的目录名称,先从当前目录的子目录进行搜索,如果没有搜索到,从当前目录的父目录开始搜索 /// </summary> /// <param name="baseDir">搜索开始的目录</param> /// <param name="targetName">目标目录名称</param> /// <param name="matchChildDir">可选需要继续匹配的目标目录下的子目录</param> /// <param name="matchChildFile">可需要继续选匹配的目标目录下的文件</param> /// <returns>如果没有搜索到,返回空字符串</returns> public string SearchSpectionFolderWithParent(string baseDir, string targetName, string matchChildDir=null, string matchChildFile=null) { Console.WriteLine("--Search Parent:{0}", baseDir); string obj = SearchSpectionChildFolder(baseDir, targetName, matchChildDir, matchChildFile); if (obj == "") { //如果子目录没有搜索到,搜索上级目录 var parentDir = System.IO.Directory.GetParent(baseDir); if (parentDir == null) return ""; return SearchSpectionFolderWithParent(parentDir.FullName, targetName, matchChildDir, matchChildFile); } return obj; } /// <summary> /// 从子目录搜索包含指定目录名称的目录,可以选择用一个子目录或者目录下面的一个文件来匹配当前是正确的目标目录(因为在其它目录下可能有重名的当前目录名称) /// </summary> /// <param name="baseFolder">当前目录</param> /// <param name="targetName">指定的目录名称</param> /// <param name="matchChildDir">可选需要继续匹配的目标目录下的子目录</param> /// <param name="matchChildFile">可需要继续选匹配的目标目录下的文件</param> /// <returns>匹配的目录名称</returns> private string SearchSpectionChildFolder(string baseFolder, string targetName, string matchChildDir, string matchChildFile) { SerachCount++; if (baseFolder == "") return ""; //搜索当前子目录 var allDir = System.IO.Directory.GetDirectories(baseFolder); foreach (var dir in allDir) { Console.WriteLine(dir); if (dir.EndsWith(targetName, StringComparison.OrdinalIgnoreCase)) { //匹配到目标目录,还需要匹配它的子目录名称或者包含的一个文件名称 if (!string.IsNullOrEmpty(matchChildDir)) { string objPath = System.IO.Path.Combine(dir, matchChildDir); if (System.IO.Directory.GetDirectories(dir).Contains(objPath)) return dir; } else if (!string.IsNullOrEmpty(matchChildFile)) { string objPath = System.IO.Path.Combine(dir, matchChildFile); if (System.IO.Directory.GetFiles(dir).Contains(matchChildFile)) return dir; } else { return dir; } } //深度优先,搜索子目录 string temp = SearchSpectionChildFolder(dir, targetName, matchChildDir, matchChildFile); if (temp != "") return temp; } return "";//未找到,返回空 } }
13,模拟死锁
在2个查询窗口分别执行执行事务1,2,将导致死锁:
--事务模拟测试2 begin tran UPDATE Table1 set END_TIME=GETDATE() where id=N'f998b30a5d384f7ebfeb4646fbed6c88'; WaitFor Delay '00:0:20'; update Table2 set END_TIME=GETDATE() where ID='94b9f18f953f4a3b837153969c6bfc1d'; WaitFor Delay '00:0:10'; Rollback tran --事务模拟测试2 begin tran update Table2 set END_TIME=GETDATE() where ID='94b9f18f953f4a3b837153969c6bfc1d'; WaitFor Delay '00:00:20'; UPDATE Table1 set END_TIME=GETDATE() where id=N'f998b30a5d384f7ebfeb4646fbed6c88'; WaitFor Delay '00:00:20'; Rollback tran
执行后,会出现下面类似的死锁信息:
消息 1205,级别 13,状态 51,第 2 行
事务(进程 ID 89)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
注意:必须在测试代码上,rollback tran 前,也增加
WaitFor Delay '00:00:20';
否则,SQLSERVER 2008 不会出现死锁,好多例子都没有这一句,是无法模拟死锁的。
除了使用Update语句,Insert语句在事务中,更容易出现死锁,比如如下的例子:
SQL1:
use DBDemo begin tran insert into [BookMarks]([BookMarkName] ,[BookMarkDesc] ,[BookMarkText]) values('人民日报合集2014','人民日报合集2015','人民日报合集2015') waitfor delay '00:00:10' select * from [BookMarks] where [BookMarkName] = '人民日报合集2014' commit tran
SQL2:
use DBDemo begin tran insert into [BookMarks]([BookMarkName] ,[BookMarkDesc] ,[BookMarkText]) values('人民日报合集2015','人民日报合集2015','人民日报合集2015') waitfor delay '00:00:10' select * from [BookMarks] where [BookMarkName] = '人民日报合集2015' commit tran
同时执行这2个查询,发现执行时间超过了语句中需要延迟的10秒,然后,其中一个查询出现了死锁:
(1 行受影响) 消息 1205,级别 13,状态 45,第 7 行 事务(进程 ID 52)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
这说明,在事务情况下,Insert语句将会使用表锁,而不是行锁,从而增大了死锁的几率。
14,Word内置的mso图标
在进行VSTO编程的时候,会有一个 ribbon.xml配置文件,用于配置自定义的功能区按钮,这些按钮的图片可以是Word内置的,如下配置:
<button id="PreviewPDF" label="预览报告" size="large" imageMso="FilePrintPreview" onAction="OnButtonClicked" screentip="预览报告" supertip="预览报告" />
那么去哪里找这些 mso图片呢?下面这个网站,可以在线浏览这些图片并获取关联的名称:
http://www.soltechs.net/CustomUI/imageMso01.asp?gal=3&count=no
15,在线操作Excel
在服务器安装Excel来操作不是一个好主意,需要复杂的COM+权限配置,并且还可能出现进程冲突,所以大家都常用第三方的Excel操作库,除了NPOI,还可以使用
16,文档开发
17,对象序列化找不到构造函数的问题
[Serializable] public class NameValueItem : NameValueCollection { /// <summary> /// 为二进制序列化提供默认构造函数 /// </summary> public NameValueItem() { } protected NameValueItem(SerializationInfo info, StreamingContext context) : base(info, context) { } public List<NameValueItem> Children { get; set; } }
18,创建数据库订阅,出现 错误22022 SQLServerAgent 的问题解决
19,SqlServer发布-订阅行数据过大无法复制的问题
选择“服务器属性”-》高级-》最大文本复制大小,默认是 65536(64K),修改成需要的数量即可。
20,Windows Server 2012 加入域(AD)后,IIS 网站访问没有权限的问题
之前,需要把网站的目录授权给 IIS_IUSRS 用户组,但是服务器加入域之后,该用户组变成了 "服务器名IIS_USRS" ,访问网站的时候提示说没有权限访问网站的文件目录。
此时,除了IIS_IUSRS 用户之外,还需要把 IUSR 用户授权给网站目录,原因是下面的说法:
IIS 7的内置用户(组)突破了SID的限制,因为IIS7在调用这些内置用户(组)时,使用的是用户名而非SID。而且在不同语言版本的系统中,IIS 7的内置用户(组)都是IUSR(IIS_IUSRS)。其中,IUSR用于取代IUSR_MachineName,IIS_IUSRS用于取代IIS_WPG。
21,浏览器执行本机应用程序
可以使用wscript.shell 执行,注意只有IE支持,并需要IE设置安全级别,HTML代码如下:
<html> <head> <title>IE调用本地程序测试</title> </head> <bodey> <h2>IE调用本地程序测试</h2> <br>请在IE下运行此程序 <script> function openFile(filename){ try{ var obj= new ActiveXObject("wscript.shell"); if(obj){ obj.Run("""+filename+""",1,false); obj=null; } }catch(e){ alert(e); } } openFile("notepad"); </script> </body> </html>
22,查询表所有的键
SqlServer可以通过下面的语句查询实现:
select * from sysobjects where parent_obj in (select id from sysobjects where name='Tb_Customer')
结果列 xtype包含 下列信息:
UQ:唯一键
PK:主键
F:外键
(本节完)