|
|
2009年05月01日
系统又要升级了,编码,测试一切好像都很正常,正当准备要上线的时候,突然发现有一个功能不能用了。这个功能就是使用HTTPS去调别的服务的WebServices。根据程序记下来的日志发现了这样的一个错误: Catched Exception: [System.Net.WebException]: "基础连接已经关闭: 接收时发生错误。" in <System.Web.Services> System.Net.WebException: 基础连接已经关闭: 接收时发生错误。 ---> System.EntryPointNotFoundException: 无法在 DLL“security.dll”中找到名为“EnumerateSecurityPackagesW”的入口点。 在 System.Net.UnsafeNclNativeMethods.SafeNetHandles_SECURITY.EnumerateSecurityPackagesW(Int32& pkgnum, SafeFreeContextBuffer_SECURITY& handle) 在 System.Net.SafeFreeContextBuffer.EnumeratePackages(SecurDll Dll, Int32& pkgnum, SafeFreeContextBuffer& pkgArray) 在 System.Net.SSPISecureChannelType.EnumerateSecurityPackages(Int32& pkgnum, SafeFreeContextBuffer& pkgArray) 在 System.Net.SSPIWrapper.EnumerateSecurityPackages(SSPIInterface SecModule) 在 System.Net.SSPIWrapper.GetVerifyPackageInfo(SSPIInterface secModule, String packageName, Boolean throwIfMissing) 在 System.Net.Security.SecureChannel..ctor(String hostname, Boolean serverMode, SchProtocols protocolFlags, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, Boolean remoteCertRequired, Boolean checkCertName, Boolean checkCertRevocationStatus, LocalCertSelectionCallback certSelectionDelegate) 在 System.Net.Security.SslState.ValidateCreateContext(Boolean isServer, String targetHost, SslProtocols enabledSslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, Boolean remoteCertRequired, Boolean checkCertRevocationStatus, Boolean checkCertName) 在 System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result) 在 System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size) 在 System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size) 在 System.Net.ConnectStream.WriteHeaders(Boolean async) --- 内部异常堆栈跟踪的结尾 --- 在同一台机器上的旧版程序,相同的代码,确可以正常使用。也是用同一个应用程序池(asp.net的程序),可以排除权限的问题。最后突然想到系统加载security.dll的时候,会不会不是加载的是系统的那个?于是再看一下程序的bin目录下,发现有一个同名的DLL,把它改名后,发现问题依旧,于是到%windir%/microsoft.net/framework/下面的asp.net cache目录下面把临时文件清除后,解决问题。 让我们顺路看看程序加载一个DLL的查找顺序吧。我用程序去引用一个根本不存在的dll,然后用filemon去看文件句柄的查找顺序: D:\PersonWork\ForTest\ConsoleApplication1\bin\Debug\ironsoftEncryp.dll D:\PersonWork\ForTest\ConsoleApplication1\bin\Debug\ironsoftEncryp.dll D:\PersonWork\ForTest\ConsoleApplication1\bin\Debug\ironsoftEncryp.dll C:\Windows\System32\ironsoftEncryp.dll C:\Windows\system\ironsoftEncryp.dll C:\Windows\ironsoftEncryp.dll D:\PersonWork\ForTest\ConsoleApplication1\bin\Debug\ironsoftEncryp.dll C:\Program Files\Borland\Delphi7\Bin\ironsoftEncryp.dll C:\Program Files\Borland\Delphi7\Projects\Bpl\ironsoftEncryp.dll C:\Windows\System32\ironsoftEncryp.dll C:\Windows\ironsoftEncryp.dll C:\Windows\System32\wbem\ironsoftEncryp.dll C:\Program Files\Microsoft SQL Server\80\Tools\Binn\ironsoftEncryp.dll C:\Program Files\Microsoft SQL Server\80\Tools\Binn\ironsoftEncryp.dll C:\Program Files\Microsoft SQL Server\90\Tools\Binn\ironsoftEncryp.dll C:\Program Files\Microsoft SQL Server\90\DTS\Binn\ironsoftEncryp.dll C:\Program Files\Microsoft SQL Server\90\Tools\Binn\VSShell\Common7\IDE\ironsoftEncryp.dll 可以总结一下查找顺序: 1. 可执行文件所在目录; 2.进程当前目录; 3.系统目录,%SystemRoot%/system32 4.16位系统目录;,%SystemRoot%/system 5.Windows目录,%SystemRoot%/ 6.环境变量PATH中的目录;
我维护的某个程序的某个httphandler需要作修改了,就是在出错三次后,需要增加图形验证码,图验正确后才继续往后台的服务发送验证信息。因为里面的逻辑比较复杂,所以我就增加了两个变量,一个是是否有图验,另一个是图验是否正确。三分钟就修改完了代码,自测了一把,一切OK,于是提交更新。过一分儿测试组的就传来消息,现在图验只出一次,以后再怎么错,就不再出图验了。 我首先怀疑是不是程序的代码不一致引起的,于是到环境上把DLL取下来,反编译,查看逻辑,一切都是一样的。 最后发现上面的IsReUseable 被置成了true.原来问题是出在这里。当这个属性被置成true后,所有的对象被创建的时候,就会放在一个对象池里,有新的请求的时候,就从池里面去取一个现成的来处理,只有当发现对象池的对象不够用的时候,才会继续创建新的对象。
2009年01月12日
有时候会碰到一些比较BT的需求,比如说想要实现avi的在线播放。有时候会发现一些工具能实现,但是发现总是不够稳定。原因在于协议,如果播放器写得好,可以一边下载,一边分析下载的流,来实现播放。但是想要实现快进,或是拖动这些的就不容易了。
要解决这些问题,只有一点,那就是自己来实现这套流协议,然后作播放器来播放。为了实现这些东西,偶作一下分析,可以简单地把技术点分为三个:
1.流服务器的实现
2.流播放器的实现
3.注册客户端,来实现播放器的关联(这样点击网页上的链接时,可以自动弹出我们的播放器来播放)
接下来让我们详细地看看具体的实现分析吧。
一、流服务器的实现
我们可以通过分析AVI的文件格格式,以及播放时的需要,可以弄出来一个很简单的流协议。并且为了方便使用,我还是基于标准的HTTP协议上来扩展实现。在这里,我把这个协议分成了两大块:媒体摘要和媒体块。
媒体的摘要:根据我们在播放AVI的时候的要求,我们的摘要里面要含有这些信息:宽,高,帧率,解码器类型,流的数量(音频和视频),推荐的缓冲大小,总帧数,如果有音频流,那还得指定音频的采样频率,位数等信息,以及每一帧的索引。
媒体块:在这里面,我们就是真正的下载数据了,每次请求的帧数,这个可以根据我们的应用环境综合考虑了,主要要考虑以下几点:下载尽量快,请求数尽量少。
有了服务器的这些支持,我们就可以实现我们的客户端了。
二、流播放器的实现
具体的播放实现我在这里就不多写了,对于媒体播放器来说,无非就是拿到一帧数据,然后调用对应的解码器解成位图数据,然后把它画在界面上。
在这里主要讲流播放器数据的请求和快进的实现:
我把程序划成两个线程:一个线程负责下载数据,另一个线程负责把内容绘在界面上。
第一步获得媒体的摘要。得到这个摘要后,我们就可以得到媒体的大概信息了。然后再顺序地把索引表发送到服务器上去请求数据。为了更好的播放性能,我们可以把下载下面的媒体块保存在临时文件里面,然后再加一个索引位置来标明每一帧的起始位,以及长度。当播放时,如果发现该帧还未下载。就给那个下载线程发个请求,让它下次下载的时候,就从这个位置开始。所以快进这些的实现就变得很简单了,如果没有下载,只要很短时间的buffer就可以继续播放了。
三、注册客户端
为了更好的体验,偶们可以注册新的协议,这样用户在点击浏览器上的链接的时候,就可以自动打开我们的播放器来播放,偶暂把这个协议定为:ivp(Ironsoft Video Protrol).注册协议很简单,只要把以下的注册导入就可以了,当然我们也可以编程实现生成这些注册表:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\IVP] @="IVPProtocol" "URL Protocol"="\"C:\\Program Files\\IronSoftPlayer\\player.exe\""
[HKEY_CLASSES_ROOT\IVP\DefaultIcon] @="\"C:\\Program Files\\IronSoftPlayer\\player.exe\",1"
[HKEY_CLASSES_ROOT\IVP\shell]
[HKEY_CLASSES_ROOT\IVP\shell\open]
[HKEY_CLASSES_ROOT\IVP\shell\open\command] @="\"C:\\Program Files\\IronSoftPlayer\\player.exe\" \"%1\""
好了,avi的在线流播放就可以很轻松地实现了。嘿嘿,偶一共是用三个工作日左右就全部实现了。
2009年01月08日
有时候开发一些应用,需要用到Office的一些组件,比如说在线生成Excel,或是Word文档。在自己的机器上跑得满好的,可是部署的时候,发现报错,如:“未能加载文件或程序集“Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”或它的某一个依赖项。系统找不到指定的文件。 ”。这个最常规的办法就是在服务器上安装一个Office。不过这太大了,而且有时候并不一定需要真的Office在上面运行。为了解决这个问题,微软发布了Office的一些更新包:Redistributable Primary Interop Assemblies. 下载地址是: Office2003: http://www.microsoft.com/downloads/details.aspx?FamilyId=3C9A983A-AC14-4125-8BA0-D36D67E0F4AD&displaylang=en Office2007:http://www.microsoft.com/downloads/details.aspx?FamilyId=3C9A983A-AC14-4125-8BA0-D36D67E0F4AD&displaylang=en 不过微软不建议我们这样来用Office。上面写了,如果把它放在asp.net或是windows服务中,Office会变得不稳定或是没有响应。这也就是为啥有时候服务器上会多很多Office相关的进程,因为没有办法正常地关闭它。
IronSoft的FlashCapture可以说是当前已知的一个唯一的可以实现flash抓图的组件,可惜它是在asp才能使用。现在跟着我来看看,如何在asp.net下面去调用它。
首先,在asp.net下添加FlashCapture的引用:
选中网站的项目,然后右键,选择“添加引用”,在弹出来的框里面选择”COM”这个选项卡,往下拉,找到”Ironsoft Library”,然后点击确定,这时候可以看到在bin目录下面添加了:Interop.IronSoft.dll.
其实就是添加代码:
FlashCaptureClass fc = new FlashCaptureClass(); fc.FileName = Server.MapPath("test.swf"); fc.CaptureFrame = 1; fc.Save(Server.MapPath("test.jpg"));
这时候你会发现图片是抓出来了,可是是一片白的。这是因为asp和asp.net的线程模型不一样了,所以出现了这样的问题,这时候我们要设置asp.net的这个页面的Asp兼容模式:AspCompat 为"true"。也就是写在asp页面的顶上,如:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="FlashCapture.aspx.cs" Inherits="FlashCapture" AspCompat="true" %>
这下子抓出来的图片里面就有内容了(IronSoft的其它组件调用如果有类似的问题,也都可以这样处理)。
最后,如果你用VS自带的服务器功能来调试的时候,会发现系统的状态栏上多了一个图标。这说明这时候FlashCapture组件并没有被释放掉。可以用以下代码来实现释放:
System.Runtime.InteropServices.Marshal.ReleaseComObject(fc); GC.Collect();
这样就轻松实现了在asp.net下面实现Flash的抓图功能了。
2008年05月04日
曾几何时,服务里面弹出一个窗口到桌面上不再是那么地容易了:以前只要把服务设置为允许和桌面交互就可以直接在服务启动的时候,把一个窗口弹给用户。但是现在在vista(其它的OS 下没有测试,未知)下要弹出这样的窗体,首先会弹出一个提示框提示是否接否一个服务弹出来的消息,点接受后,才会在一个全灰的桌面里面弹出这个窗口。不用想,这样的用户体验,肯定是会被直接PASS。原因很简单,因为不同的用户间的桌面是不一样的,服务用的是System的权限,在vista里面是Session0,而用户的帐户不是这个(肯定大于0)。
看来,想弹出一个窗体,需要另一个程序来作辅助了。解决方案有两种:
- 开发一个程序A在启动的时候,随系统启动,并监控指定文件M,服务S有消息的时候,放在文件M里,A 感受了文件变化了,就去读这个文件里的内容,根据规则来作对应的动作。坏处很明显,当用户为了让系统跑得快的时候,这种自启动文件很容易被砍掉,导致了有些功能莫名奇妙地不可用。
- 同样地,也是开发一个程序A,用CreateProcessAsUser这个API来创建这个A ,并且发送到用户的桌面上去。好处是可以把这个A和服务S 放在同一个程序文件里面,根据不同的参数来启动不同的功能。这样用户除非是删除整个服务,否则不会有部分功能能用,又有部分功能不能用的问题。
现在来看看第二种方案,要想用CreateProcessAsUser这个API ,有这样几个步骤:
1.取得用户的令牌(Token)
2.指定好虚拟桌面
3.调用API创建这个用户进程。
在取得用户令牌的时候,又有几个方法:
1.从用户的进程上去剥
2.先用WTSGetActiveConsoleSessionId得到用户会话ID,再用WTSQueryUserToken这个API去取。
不过在vista下面,服务里面的WTSGetActiveConsoleSessionId这个API得到的总是0,也就是Session0,用这个创建出来的进程,还是属于一个服务进程。(而且这个API是XP以及以后的系统才会提供的,在早点的系统上就会调用失败)所以我们只好从用户的进程上去找,用户登录的时候,一定会有的进程就是:explorer.exe,这样可以遍历所有的进程去找到这个(如果是多人同时登录这个系统里,我也不知道该怎么办了,不知道有没有高人指点一下)。
这样创建出来的用户进程,在进程列表里面可以看到是活动用户的。但是如果在这里面使用一下文件选择框,或是去取一些系统目录,比如说用户的桌面,用户的收藏夹等,都会得到空。这时候因为没有指定用户环境造成的。使用CreateEnvironmentBlock这个API就可以搞定了。
2007年10月22日
cmdlet虽然编译后是一个程序集,但是它内嵌于powershell.exe中运行,所以它的配置文件用app.config就不太适合了,得用powershell.exe.config,发现原来没有,就自己加一个过去,改个名就可以了. 今天碰到一个让人狂晕的问题,那就是明明在配置文件里面加了配置项了,但是在程序里面死活读不到,于是到处找,因为之前已经给cmdlet加了config,并给里面配置了一个connectionstring,但是这次加的两个appsetting不生效.最后发现那个修改的文件的最后修改日期还是停在了上次的时间,并没有更新过来,但是打开文件的时候,又可以看到完整内容.一个比较恐怖的念头出现了,那就是系统不知道用了什么策略为了保护windows目录下面的文件,不能去写文件,只能够用覆盖的方式来实现。(我的机器是Vista,发现所有的Windows等核心目录里面自己弄的文件全放在%userprofile%\AppData\Local\VirtualStore\目录下,估计这是为了保护系统,以及为了能比较好地恢复系统吧)。 Cmdlet在使用的时候,可以用$v=cmdlet 这种方式把cmdlet的输出保存给变量,特别是输出的是对象或是列表的时候,这样获取值还可以传给后面cmdlet的继续使用.在为了把输出的对象列表格式发成一个表格的时候,花了偶N多时间,因为系统提供的例子是Get-Process这个例子,得到的进程列表信息输出的时候,不用任何的操作就可以直接输出成一个列表,但是自己写的对象,死活以一种不专业的形态输出来:属性名:值 这样一行一行地输出来。开始我总觉得是对象实现了某一个接口或是某个attribute起了作用,自己尝试去实现这些,可是就是不行。最后突然想到了powershell目录下面的那些ps1xml文件,拿editplus打开它们,发现原来这些会自动列表的对象在这里面都定义好了每个字段可以显示成什么名字,以及列宽什么的。因为没有时间了,所以只好先在输出的时候用format-table这个管道来格式化成列表,以后再研究怎么修改这些ps1xml。 现在感觉有两个地方让人不爽了,一个就是配置文件不能随着cmdlet的plugin文件走,另一个就是对象列表的说明还要自己搞ps1xml来描述,这对于cmdlet的分发造成了不便。这东西给别人用的时候,只好写上把config和原来的合并一下,把ps1xml复制到运行目录上。在MSDN里面有看到一个make-shell命令,但是本机运行的时候,没有发现这个命令,GOOGLE的时候,发现那是UNIX上的。
2007年09月24日
认清了Cmdlet的生存周期和执行的顺序对于我们后续的开发和使用有相当重要的意义,因为它直接决定了到时候该怎么开发,能实现哪些功能(比如说一直需要运行的程序,就不适合用Cmdlet来完成)。
先让我们看一下Cmdlet的生存周期: 1: [Cmdlet(VerbsCommon.Add, "Test")] 2: public class AddTest: Cmdlet 3: { 4: 5: protected override void BeginProcessing() 6: { 7: WriteObject("BeginProcessing"); 8: } 9: 10: protected override void ProcessRecord() 11: { 12: WriteObject("ProcessRecord"); 13: base.ProcessRecord(); 14: } 15: 16: protected override void EndProcessing() 17: { 18: WriteObject("EndProcessing"); 19: base.EndProcessing(); 20: } 21: 22: protected override void StopProcessing() 23: { 24: WriteObject("StopProcessing"); 25: base.StopProcessing(); 26: } 27: 28: } 我们可以发现,结果是:
BeginProcessing ProcessRecord EndProcessing
基本上和我们猜测的一样的,初始化,执行,完成
可以判断StopProcessing这是在Cmdlet被中止的时候才会触发的。
再让我们看一下Cmdlet的生存周期:
1: public class TaskManager 2: { 3: private static int runCount = 0; 4: public static int Run() 5: { 6: return runCount ++; 7: } 8: }
1: [Cmdlet(VerbsCommon.Add, "Test")] 2: public class AddTest: Cmdlet 3: { 4: protected override void ProcessRecord() 5: { 6: WriteObject(TaskManager.Run()); 7: base.ProcessRecord(); 8: } 9: } 运行这个Cmdlet,多次运行,以及关掉PS后,重新加载后执行的情况来看,我们可以看出:Cmdlet所在程序集从Add-PSSnapIn加载到PowerShell里后,也就是这个DLL被启动起来了,直到这个PowerShell被关掉,完成它的一个生命周期.也就是说,在这运行过程中,我们可以把很多数据记录在静态成员里面,比如说运行的记录等.
2007年09月18日
PowerShell是微软最新推出的基于脚本的管理工具,用脚本管理的好处就是便于写批处理命令.相象一下大的IT公司里面要把数千台的服务器上的没有响应的IIS重启一下,那是一种多么大的工作量,有了PowerShell后,那就显得轻松很多了,先一个命令查出哪台没有响应了,再发送重启命令,一切都可以自动化地完成.同时容易适应不断变化着的意外情况可以轻松地调整脚本.
因为工作需要,开始学习和使用PoswerShell来做应用开发.目标是把当前的一些功能封装成cmdlet(command-let小命令),同时研究如何在C#里面去调用cmdlet.先看看资源:
PowerShell的下载地址:http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx
请注意你当前的系统以及CPU类型选择下载.
微软的PowerShell官方BLOG:http://blogs.msdn.com/powershell/
MSDN中的相应说明:http://msdn2.microsoft.com/en-us/library/aa139691.aspx
开发的时候,需要PowerShell的SDK,可以从这里下载(现在只有for vista的):http://www.microsoft.com/downloads/details.aspx?FamilyId=C2B1E300-F358-4523-B479-F53D234CDCCF&displaylang=en (SDK又是那种先下个小文件再下大文件的那种,比较郁闷)
再看一眼传说中的PowerShell,和原来的CMD很像:
输入help就可以看到所有的命令,包含CMD的命令和一些cmdlet,不过就这些就够我们翻一会儿了.
先写到这里,其它的在下面的日子里,会渐渐地写完.
安装完windows Vista SDK后,终于可以开始CmdLet的开发了.如果安装了Samples的同学,可以直接去看示例:X:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\SysMgmt\WindowsPowerShell 其中X是PS所在的安装盘.下面让偶手把手地说一下该怎么建立一个CmdLet吧:
1.打开VS2005,创建一个windows的运行库.
2.添加引用:C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll
3.新建一个类文件,同时
using System.Management.Automation; using System.ComponentModel;(这个在安装时会用到)
4.下面开始写代码了: //先来完成cmdlet的实体类
[Cmdlet(VerbsCommon.Get, "HelloWorld")] //大胆地猜测一下,PS在加载cmdlet程序集的时候,是用反射的方式来识别的,反射的时候就是靠这个attribute来实现,这里面有两个参数,第一个是动作,后一个是名字.这是cmdlet的命名方式:动词+名词 public class ExecuteShell : Cmdlet // 继承自cmdlet的基类 { private string argus; [Parameter(Position = 0)] //大家可以发现很有意思在这里面,随处都可以看到attribute,这里指写了第一个参数,直接就反射到类对应的属性上了. [ValidateNotNullOrEmpty] public string Args { get { return argus; } set { argus = value; } }
protected override void ProcessRecord() //处理请求,我们我这里只是简单地输出一下信息.
{ if (argus != null && argus.Length > 0) { WriteCommandDetail("Hello World:" + argus); } }
}
//再来看看cmdlet的安装类
[RunInstaller(true)] //又是这种attribute
public class HelloWordSnapIn: PSSnapIn { /// <summary> /// Create an instance of the GetProcPSSnapIn01 /// </summary> public PSclient() : base() { }
/// <summary> /// Get a name for this PowerShell snap-in. This name will be used in registering /// this PowerShell snap-in.
/// 注意这里面的名字最为重要在下面将要讲到 /// </summary> public override string Name { get { return "HelloWordSnapIn"; } }
/// <summary> /// Vendor information for this PowerShell snap-in. /// </summary> public override string Vendor { get { return "BrainIron"; } }
/// <summary> /// Gets resource information for vendor. This is a string of format: /// resourceBaseName,resourceName. /// </summary> public override string VendorResource { get { return "HelloWordSnapIn,BrainIron"; } }
/// <summary> /// Description of this PowerShell snap-in. /// </summary> public override string Description { get { return "This is a PowerShell snap-in that includes the Get-HelloWorld cmdlet. this is a demo, design by Brian"; } } }
编译生成:HelloWorldCmdLet.dll
6.这时候该安装了:使用Installutil.exe HelloWorldCmdLet.dll来把安装它.Installutil.exe如果你找不到,那么应该在SDK的BIN目录里面肯定可以找得到.
7.这时候打开PS,使用Get-HelloWorld 命令会发现提示不支持这个命令.这时候要用:Add-PSSnapin HelloWordSnapIn 来把它注册到PS的控制台中,这个命令的后面的那个名字就是我上面说的重要的名字,而不是类名.然后再用Get-HelloWorld 命令就可以看到成果了.
8.调试.因为程序要先注册到PS中,PS才能调用,所以好像不太好调试,其实可以用附加到进程的方式来调试.
2007年05月13日
突然间发现Vs2003无法在IIS7上面进行调试,首先是提示现在的localhost所在的区域在Internet区.所以很快我就把它加入到了信任站点区域,并且设置了自动以当前帐户登入.可是提示却成了:你确认你是"Debug Users"组的用户,于是我又把当前帐户和Administrators加入了"Debug Users"组里.从此以后再也无法进行调试,一直是这个错误提示.
老铁匠我只好搬出了万能的GOOGLE,但是这次好像也没有帮上什么忙,找到的最有价值的一篇文章也是博客堂上的<如何在Vista IIS 7 中用 vs2005 调试 Web 项目? >按照上面所说的重新设置了一轮,可是还是一样的错误.再往下找,有的甚至说IIS7已经不支持VS2003了,建议使用VM或是VPC来搞个XP或是2003来作Asp.net 1.1的开发.
只好到处转转,突然想起来匿名帐户是没有调试权限的,而根据上一篇文章所写的是把匿名帐户的验证也允许了,所以即使调试,可能IIS7认为当前的帐户是匿名帐户,而不是我现在所用的帐户,于是把匿名帐户的验证禁用了。再次按下F5键,突然地,发现它不报错了,断点成功地停住了。
事后发现,好像只要在IE里面把localhost设置为信任站点,并且设置了自动以当前帐户登入;同时按<如何在Vista IIS 7 中用 vs2005 调试 Web 项目? >且把匿名帐户的验证禁用就可以解决无法调试的问题。欢迎大家尝试:)
2007年04月09日
初用IIS7让人一头雾水,再也没有原来熟悉的属性窗体,替代的是一些很陌生的名词和操作方式.现在不评它这种改变是好是坏,先让它给我们跑起来吧(老铁的机子运行的是中文版的VISTA,所以里面的名词都是基于中文版的,如果使用其它版本的朋友,请对照着找找^!^):
首先是安装IIS7: Vista默认的情况下是没有安装IIS7,所以我们要在"控制面板"里面的"程序和功能"里面点击"打开或关闭Windows功能",在里面把对应的IIS的功能钩上,铁匠友情提示你,如果想要IIS7运行ASP.NET 1.1的程序,你需要把IIS6兼容性的这些选项一起选中.
其次是配置ASP.NET2.0 对于ASP.NET2.0来说,一切要简单些,因为IIS7默认情况下是支持ASP.NET2.0的程序,只是需要自己重新建一个应用程序池,选好.Net Framework的版本2.0的,托管管道的方式选成:经典.这样应该就OK了.
对于ASP.NET 1.1的配置 对于ASP.NET 1.1来说,就要复杂好多,因为IIS7一般是在.NET FrameWork 1.1后装的,所以要用:%windir%\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis -i 来注册你的.NET FrameWork 1.1,但是这时候你查看你的站点的时候,只要一运行ASP.NET的页面,IIS就挂掉了,这时候,老铁经过大量的实践和搜索可以很负责任地告诉你,你没有装.NET FrameWork 1.1 SP1 具体的下载地址是:http://www.microsoft.com/downloads/info.aspx?na=22&p=3&SrcDisplayLang=en&SrcCategoryId=&SrcFamilyId=&u=%2fdownloads%2fdetails.aspx%3fFamilyID%3da8f5654f-088e-40b2-bbdb-a83353618b38%26DisplayLang%3den。装完这些后,再在池里面加上对应的应用程序池,然后设置站点,一切就OK了。
最后说说ASP的设置 作为一个经典的WEB框架,有时候还是得放些ASP的页面在自己机子上看看的,所以让我们一起让IIS7支持ASP吧:首先得看看是不是安装上了ASP的支持,还是在“打开或关闭Windows功能”里面,IIS下的万维网服务,应用程序开发功能里面把对应的项勾选,这时候站点里面就有ASP的选项出来了,在IIS的程序映射里面会有ASPClassic,默认的情况下应该是禁用的,这时候要编辑一下运行权限,把它启用。如果这时候还不能查看,那应该是权限还是不够,可以用以下的方式来修改:在C:\Users\Default\AppData\Local下的Temp加上Users的权限。这时候应该就OK了(因为我是很久之前进行这个设置的,所以有些记不太清了,不过相对来说,这个的设置要比ASP.NET 1.1容易很多).
|