[原创]SQLServer存储过程中特殊字符的like查询

mikel阅读(920)

目前遇到的问题是查询字符串中含有“【】”后,存储过程Like查询不出结果,原存储过程代码如下:

ALTER PROCEDURE [dbo].[Base_CompanySelect]
	@PageSize int=0,
	@CurrentPage int=1,
	@Identifier int=NULL,
	@Company_Name nvarchar(50)=NULL
AS
BEGIN
	SET NOCOUNT ON;
	IF (NOT @Company_Name IS NULL)	
	BEGIN
		SET @Company_Name='%'+@Company_Name+'%'
        END

        SELECT * FROM base_Company WHERE company_Name like @Company_Name
GO


解决办法,就是先将“【】”进行转译,然后利用SQL模糊查询语句和Escape转义字符中的Escape函数进行Like查询,修改后的代码如下:

ALTER PROCEDURE [dbo].[Base_CompanySelect]
	@PageSize int=0,
	@CurrentPage int=1,
	@Identifier int=NULL,
	@Company_Name nvarchar(50)=NULL
AS
BEGIN
	SET NOCOUNT ON;
	IF (NOT @Company_Name IS NULL)	
	BEGIN
		SET @Company_Name='%'+@Company_Name+'%'
		SET @Company_Name=replace(@Company_Name,'[','\[')
		SET @Company_Name=REPLACE(@Company_Name,']','\]')
        END

        SELECT * FROM base_Company WHERE company_Name like @Company_Name E s c a p e('\')
GO

[转载]两分钟完成网上订票从登录到付款

mikel阅读(943)

[转载]开源项目助我回家–两分钟完成网上订票从登录到付款 – jiangzhuo – 博客园.

本文中提到的代码全部来源于网上的开源项目

花了不到两个小时拼凑而成的程序就可以实现两分钟从登录到付款的全部操作.

下面是正文

要解决的问题:

1登录不上去

2登录上去后提交不上订单

3提交上订单后付款不成功要重新登录

开始解决问题:

首先要有一个从登录到订票全部流程的实现,而且要自动化的实现。从登录到订票这个流程codeplex上的一个开源项目

TrainSearch http://myticketsearch.codeplex.com/ 基本实现了 而且结合了Webbrowser空间可以在登录成功后共用一个session,实现网页不用再次登录。

但是这个项目不够自动化要手动输入验证码

于是本人最初的修改是利用Tessocr进行验证码识别(利用Tessocr受到了Java的订票开源项目的启发 http://code.google.com/p/go-home/

之后发现有人利用验证码不刷新的BUG(虽然早知道有这个BUG 但是没有想到他们竟然六个月不修这个BUG) 于是修改了下代码的逻辑之请求一次验证码。

这样就解决了前两个问题

最后一个问题就是付款  付款要再登录啊 什么坑爹的逻辑啊

而且由于我们Webbrowser维持的session会因为“网上支付”那个按钮是target=”_blank” 会弹出新的IE窗口传递不了我们Webbrowser维持的Session

这里就需要不弹出IE 于是用到了又一个开源项目ExtendedWebBrowser http://www.codeproject.com/KB/cpp/ExtendedWebBrowser.aspx

这样Session的问题解决了 不用登录那个破网页 直接一个程序解决了 下面程序截图

[转载]JavaScript获取客户端MAC地址

mikel阅读(978)

[转载]JS获取客户端MAC地址 – gsbhz – 博客园.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>JS获取客户端MAC地址</title>
   <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
   <meta name="generator" content="editplus" />
   <meta name="author" content="" />
   <meta name="keywords" content="" />
   <meta name="description" content="" />
   <style type="text/css">
 
   </style>
     <script event="OnObjectReady(objObject,objAsyncContext)" for="foo"> 
         if(objObject.IPEnabled != null && objObject.IPEnabled != "undefined" && objObject.IPEnabled == true) { 
             if(objObject.MACAddress != null && objObject.MACAddress != "undefined" && objObject.DNSServerSearchOrder!=null) 
                 MACAddr = objObject.MACAddress; 
             if(objObject.IPEnabled && objObject.IPAddress(0) != null && objObject.IPAddress(0) != "undefined" && objObject.DNSServerSearchOrder!=null) 
                 IPAddr = objObject.IPAddress(0); 
             if(objObject.DNSHostName != null && objObject.DNSHostName != "undefined") 
                 sDNSName = objObject.DNSHostName; 
         } 
     </script>
     <script type="text/javascript">
         var MACAddr ; 
         var IPAddr ; 
         var DomainAddr; 
         var sDNSName; 
         function init() {
             var service = locator.ConnectServer(); 
             service.Security_.ImpersonationLevel=3; 
             service.InstancesOfAsync(foo, 'Win32_NetworkAdapterConfiguration'); 
         }
 
         function getMac() {
             document.getElementById('txtMac').value = unescape(MACAddr);
         }
     </script>
  </head>
 
  <body onload="init()">
     <object id="locator" classid="CLSID:76A64158-CB41-11D1-8B02-00600806D9B6" VIEWASTEXT></object> 
     <object id="foo" classid="CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223"></object> 
 
     <input type="text" id="txtMac" />
     <input type="button" id="btn" value="获取Mac地址" onclick="getMac();" />
  </body>
 </html>

[转载].NET正则表达式之替换类高级技巧

mikel阅读(1062)

[转载].NET正则表达式之替换类高级技巧 – 水行者 – 博客园.

因为.net的基本正则语法和Perl5基本相同,所以基本语法你可以去下载一下M$的JS帮助文 档,上面有详细的说明\d表示什么,{,5}表示什么,\[表示什么……,这里我只想提醒大家一点,为了避免和反向引用相冲突,在你用\nn表示八进制的 ASCII码时,请在\后加0,就是说,\40在表示ASCII码时,请这样写\040。 powered by 25175.net

替换

Regex类有一个静态的Replace方法,其实例也有一个Replace方法,这个方法很强大,因为它可以传入一个delegate,这样,你可以自定义每次捕获匹配时,如何处理捕获的内容。

public static void Main()
{
string s = “1 12 3 5”;
s = Regex.Replace(s,@”\d+”,new MatchEvaluator(CorrectString),RegexOptions.Compiled|RegexOptions.IgnoreCase);
Console.WriteLine(s);
Console.ReadLine();
}
private static string CorrectString(Match match)
{
string matchValue = match.Value;
if(matchValue.Length == 1)
matchValue = “0” + matchValue;
return matchValue;
}

以上这段代码说明了如果使用delegate MatchEvaluator 来处理正则的Match结果,该代码返回”01 12 03 05″。Replace方法除了使用delegate来处理捕获的Match,还可以用字符串来替换Match的结果,而用字符串来替换Match结果除 了把Match结果静态的替换成一个固定的文本外,还可以使用以下语法来更方便的实现你需要的功能:

$number 把匹配的第number组替换成替换表达式,还有这句话怎么写也表达不清楚意思,还是来个例子吧:

public static void Main()
{
string s = “1 12 3 5”;
s = Regex.Replace(s,@”(\d+)(?#这个是注释)”,”0$1″,RegexOptions.Compiled|RegexOptions.IgnoreCase);
Console.WriteLine(s);
Console.ReadLine();
}

这段代码返回的是 “01 012 03 05”

就是说,对组一的每个匹配结果都用”0$1″这个表达式来替换,”0$1″中”$1″由组1匹配的结果代入

${name} 把匹配的组名为”name”的组替换成表达式,

上例的Regex expression改成@”(?<name>\d+)(?#这个是注释)”后面的替换式改为”0${name}”结果是一样的

$$ 做$的转义符,如上例表达式改成@”(?<name>\d+)(?#这个是注释)”和”$$${name}”,则结果为”$1 $12 $3 $5″
$& 替换整个匹配
$` 替换匹配前的字符
$’ 替换匹配后的字符
$+ 替换最后匹配的组
$_ 替换整个字符串

后面的选项,大家自己写个例子体味一下。

*注,上例中的(?#这个是注释)说明了正则的内联注释语法为(?#)

表达项选项

正则表达式选项RegexOptions有如下一下选项,详细说明请参考联机帮助

RegexOptions枚举值 内联标志 简单说明
ExplicitCapture n 只有定义了命名或编号的组才捕获
IgnoreCase i 不区分大小写
IgnorePatternWhitespace x 消除模式中的非转义空白并启用由 # 标记的注释。
MultiLine m 多行模式,其原理是修改了^和$的含义
SingleLine s 单行模式,和MultiLine相对应

这里我提到内联标志,是因为相对于用RegexOptions在new Regex时定义Regex表达式的全局选项来说,内联标志可以更小粒度(以组为单位)的定义匹配选项,从而更方便表达我们的思想

语法是这样的:(?i:expression)为定义一个选项,(?-i:expression)为删除一个选项,(?i-s:expression) 则定义i,删除s,是的,我们可以一次定义很多个选项。这样,通过内联选项,你就可以在一个Regex中定义一个组为匹分大小写的,一个组不匹分大小写 的,是不是很方便呢?

[转载]细说 ASP.NET控制HTTP缓存

mikel阅读(1115)

[转载]细说 ASP.NET控制HTTP缓存 – Fish Li – 博客园.

在上篇博客【细说 ASP.NET Cache 及其高级用法】中, 我给大家介绍了ASP.NET Cache,这种服务端使用的缓存API 。在我们开发一个ASP.NET网站的过程中,其实有很多地方都是可以使用缓存的, 只是由于ASP.NET是一种基于服务端的开发平台,自然我们也经常在服务端的代码中使用各类缓存技术, 然而,由于WEB应用程序的服务对象是客户端的浏览器,通常来说,我们并不能直接控制浏览器的行为,但是, 浏览器却可以根据后台网站的指示,采取一些优化的方式来更快地呈现页面。 客户端浏览器也有自己的缓存机制,通常浏览器也使用缓存来优化一些页面的显示过程, 不过,我们并不能直接使用C#代码控制浏览器的缓存操作,但我们可以告诉浏览器如何使用缓存,从而达到优化网站性能的目的。

这次博客的主题是:用ASP.NET控制HTTP请求过程中浏览器缓存的一些方法。

正常的HTTP请求过程

在开始介绍浏览器在HTTP请求过程前,我想有必要先来看一下浏览器请求一个普通ASPX页面的过程。
说明:本文在介绍HTTP请求过程时,会大量使用Fiddler来分析具体的请求过程。

上图是一个普通的ASPX页面的请求过程,说它普通是因为:我在创建这个页面后,没对它做任何缓存方面的处理。
图片中我们可以可以看到服务器的响应状态为:HTTP/1.1 200 OK,这是一个服务器成功响应的标志。
另外,要注意图片中的Cache响应头部分,我之所以就红线框出来,是想提醒您注意这块的内容将在后面的小节中发生改变, 到时候请注意对比它们。而这里所反映的情况其实也只是默认值而已,它并不表示此页面需要缓存。

缓存页的请求过程

下面再来看一个缓存页面的请求过程:

对比上一张图片中可以看出,现在多了【max-age】,【Expires】以及【Last-Modified】这三个响应头。

这三个头的含义如下:
1. max-age,Expires:要表达的意思基本差不多。max-age表示某次HTTP的响应结果应该缓存多少秒。
而Expires是说某次HTTP的响应结果应缓存到什么时候过期,此时间是一个UTC时间。
另一个Date头表示HTPP响应的发出时间,我们可以发现 Date + max-age = Expires
2. Last-Modified:服务端告诉客户端本次响应返回的HTTP文档的最后修改时间。这个头与304的实现有关,后面再来解释。

分析了HTTP请求过程后,我们再来看一下服务端的页面是什么样子的: 『点击此处展开』

注意:上面代码中最关键的一行代码为:

<%@ OutputCache Duration="10" VaryByParam="None" %>

正是由于使用了这个OutputCache指令,最后才会输出上面那几个响应头,用来告诉浏览器此页面需要缓存10秒钟。

说到这里,可能有些人想有疑惑了:缓存页在什么时候会起到什么作用呢?
为了演示缓存页所带来的现实意义,我将点击页面的这些链接并以截图的形式来说明:在一系列请求过程中页面的显示情况, 并以页面的显示结果来分析缓存所起的作用。

先来看看这个页面的显示截图:

页面很简单,主要是显示了页面的生成时间与一个刷新链接。 从上面提供的页面代码,我们应该能知道这个页面如果是由服务端生成的,则会显示当前的时间。

不过呢,当我一直(频繁)点击【刷新本页】那个链接时,页面的时间并没有发生改变,当我发现时间改变时,页面已显示成这个样子了:

由于测试过程中,我一直打开了Fiddler,正好我也把Fiddler监视到的请求结果截图下来了:

从Fiddler中,我看到FireFox其实只发生了二次请求,但我点击那个【刷新本页】起码超过10次。

以上的这一切,只说明一个事实:如果页面需要跳转到某个缓存页时,且那个缓存页还没过期,那么浏览器并不会发起到服务器的请求,而是使用缓存页。

小结:页面缓存所带来的好处是:缓存页面在过期前,用户通过点击跳转链接所引发的后续访问,并不会再次请求服务器。 这对服务器来说可以减少许多访问次数,因此使用这个特性可以很好地改善程序性能。

缓存页的服务端编程

前面演示了使用OutputCache指令所产生的缓存页的效果,由于那些指令需要在页面的设计阶段就写到页面上,因此显得不够灵活, 不能在运行时调整,虽然ASP.NET也允许我们使用CacheProfile来引入定义在Web.config中的配置,但配置还是没有运行时的代码灵活。 我们再来看看如何用代码来实现上面的效果。

其实用代码实现缓存页也很简单,只需要这样就可以了:

protected void Page_Load(object sender, EventArgs e)
{
    Response.Cache.SetCacheability(HttpCacheability.Public);
    Response.Cache.SetExpires(DateTime.Now.AddSeconds(10.0));
}

其实关键也就是对Response.Cache的调用。
注意:Response.Cache与我上篇 【细说 ASP.NET Cache 及其高级用法】博客所讲的Cache不是一回事,二者完全不相干。
Response.Cache提供:用于设置缓存特定的 HTTP 标头的方法和用于控制 ASP.NET 页输出缓存的方法。

我们还是来说前面的二段示例代码。可能有些人会想,它们最终的结果真的会是一致的吗?

要想回答这个问题,我想有必要看一下前面用OutputCache指令的那个页面最终运行的代码是个什么样子的。

在ASP.NET的临时编译目录中,我找到了前面那个文件的一个由ASP.NET处理后的版本: 『点击此处展开』

我们可以看到页面针对OutputCache指令的设置,最终会调用Page类定义一个方法中:

protected internal virtual void InitOutputCache(OutputCacheParameters cacheSettings)

那个方法实在太长,最终的处理方式也还是在调用this.Response.Cache,有兴趣的可以自己去看看那个方法。 至于这个方法的参数为什么是OutputCacheParameters,我想这个容易理解:方便将OutputCache指令的参数全部一起传入嘛。

所以,也正因为这个缘故,我们也可以直接在代码中调用Response.Cache的一些方法来实现相同的效果, 由于代码可以在运行时根据各种参数调整缓存策略,因此会更加灵活,而且可以采用基类的继承方式来简化实现。

注意:如果使用OutputCache指令再配合OutputCache Module的使用,可以实现304的效果。

什么是304应答?

通过前面的示例,我们已经看到缓存带来的好处:那就是可以减少到服务器的访问,由于不访问服务器就能显示页面,这对于服务器来说, 能减轻一定的访问压力。但是,如果用户强制刷新浏览器,那么浏览器将会忽略缓存页,直接向服务器重新发起请求。

也就是说:缓存页在用户强制刷新浏览器时会无效。
但是,我们之所以使用缓存页,是因为我们希望告诉浏览器:这些数据在一定时间内,并不会发生变化,因此根本不需要再次请求服务器了。 然而,我们不能阻止用户的行为。由于浏览器的重新访问,我们原来设想的缓存想法将会落空,最后的结果是: 页面在服务器中重新执行,产生的HTML代码将重新发送到客户端。而这一重新刷新的结果可能也是无意义的,因为数据可能根本没有发生变化, 因此得到的页面也是不可能有变化的。

再来举个简单的例子来说吧:客户端要浏览一张图片。 当浏览器第一次要访问图片时,浏览器肯定是没有它的任何缓存记录的,此时它去访问服务器,服务器也返回图片的内容了。 但由于图片可能会被多个页面所引用,而它被修改的可能性是很小的。 因此没有必要为同一浏览器的多次请求都去读取图片并返回图片的内容,这样做既影响性能也学浪费带宽。 于是,像IIS这样服务器软件针对这类静态文件的访问时,都会在响应头上输出一些标记,用来告之浏览器这个文件你可以缓存起来了。

还是回到前面所说的【用户强制刷新】问题,此时的IIS又会如何处理呢?请看下图:

注意哦,此时除了HTTP状态码变成304之外,没有任何数据返回哦。

为了让您对304应答有个深刻的印象,我截了一张状态码为200的图片响应结果:

通过这二张图片的对比,现在看清楚了吧:304和200并不只是数字上的差别,最重要的差别在于有没有返回结果。

没有返回结果,浏览器该如何显示?
您会有这样的疑虑吗?
其实不用担心,此时浏览器会使用它缓存版本来显示。也就是说:不管用户如何强制刷,服务器就是不返回结果,但仍然可以正常显示。

显然,这个效果就是我们想要的。
前面所说的缓存页遭用户强刷的问题,如果采用这种方法,就比较完美了。
不过,有一点我要提醒您:Visual Studio自带的那个WebDev.WebServer.exe不支持304应答,所以您就不要拿它试验了,不会有结果的。

如何编程实现304应答

前面我们看到了304应答的效果。不过,在ASP.NET中,我们开发的程序,是动态页面,而不是图片, 我们更希望某个页面能以这种方式缓存一段时间,我想这个需求或许会更有意义。

下面,我就来演示如何通过编程的方式实现它。
接下来的示例中,页面的显示还是那个样,显示页面在服务器上产生的时间,时间变化了,说明页面被重新执行了。

重新截一系列的图片,我认为意义也不大,我就截一张图片展现多次强刷而产生的过程

上图反映了我多次请求某个ASPX页面的过程,从图片中可以看出,只有第一次是200的响应,后面全是304,是您所期待的结果吧。

再来看看它的实现代码吧: 『点击此处展开』

虽然代码并不复杂,但我还是打算来解释一下:
在浏览器第一次请求页面时,会执行SetLastModified的调用,它会在响应时输出一个”Last-Modified”这个响应头, 然后,当浏览器再次访问这个页面时,会将上次请求所获取的”Last-Modified”头的内容 , 以”If-Modified-Since”这个请求头的形式发给服务端,此时服务器就可以根据具体逻辑来判断要不要使用304应答了。

在前面的请求图片的示例中,服务器以图片文件的最后修改时间做为”Last-Modified”发给浏览器, 浏览器在后续请求那张图片时,又以”If-Modified-Since”的形式告之服务端,此时服务端只要再次检查一下这张图片就知道图片在上次访问后有没有发生修改, 如果没有修改,当然就以304的形式告之浏览器:继续使用缓存版本。

还是前面的请求图片的示例,其实服务端还使用了另一对【请求/响应】头:

这二个头的使用方式是:服务端输出一个ETag头,浏览器在接收后,以If-None-Match的形式在后续请求中发送到服务端, 供服务端判断是否使用304应答。

“Last-Modified”与”ETag”这二者,事实上只需要使用一个就够了,关键还是看服务端如何处理它们,浏览器只是在接收后,下次再发出去而已。

不过,前面的示例代码并没有使用缓存头,事实上,也可以带上它,这样可以尽量减少对服务器的访问,毕竟用户不会一直强刷浏览器。 这二种方式虽然有较大差别,但它们绝对是可以互补的。

为了能形象的描绘缓存页(或者其它文档)的请求过程,我画了张示意图供大家参考:

如何避开HTTP缓存

前面小节中,介绍了二种方法使用浏览器的缓存。但有些时候可能反而希望浏览器能放弃它缓存的结果。 现在的浏览器都有缓存功能,尤其是对一些静态文件,比如:图片,JS,CSS, HTML文件,都能缓存。 但有时候我们需要更新CSS, JS文件呢,浏览器如果还使用它的缓存版本,显然就有问题了。 而且有些网站使用了URL重写,使原来的动态页面扩展名也变成静态的HTML文件了, 因此,仍然希望浏览器在某些时候能够不要缓存这些伪静态页面。

此时,我们就希望浏览器放弃从HTTP请求所获得的结果了。 一般说来,浏览器在处理(它认为的)静态文件时,会按照URL为kEY来保存那些缓存结果, 因此,通常的解决办法也就是修改URL,比如:原来是请求abc.js的,要改成abc.js?t=23434,后面要跟上一个参数, 让以前的缓存不起作用。至于参数t的取值可以根据文件的最后修改时间,也可以手工指定,总之只要改变它就可以了。

但是,对于伪静态的页面,我们不能再使用这种方法了,原因就不用解释了吧。
那么,可以采用在服务端输出一个响应头,通过响应头的方式告之浏览器,不要缓存此文件。 比如,可以调用这个方法:

Response.Cache.SetNoStore();

它会生成这样的响应头内容:

Cache-Control: private, no-store

许多浏览器都能识别它。还有另一种方法是设置一个已过期的过期时间。

前面所说的在URL中加额外参数的做法,在JS中也比较常用,比如 JQuery就支持让某个Ajax请求不缓存, 它的方式就是设置{cache: false},最终它便会在生成的URL中加上一个临时参数,以保证后面的请求的地址是不重复的, 最终达到避开缓存的目的。JQuery的使用太简单,我就不再给出示例代码了。

点击此处下载示例代码

[转载].net 2.0下的OOXML神器:NPOI.OpenXml4Net

mikel阅读(1205)

[转载].net 2.0下的OOXML神器:NPOI.OpenXml4Net – Tony Qu – 博客园.

作者:Tony Qu

NPOI官方博客:http://tonyqus.sinaapp.com | 官方QQ群:189925337

可 能很多人已经习惯了使用.Net 3.0下的System.IO.Packaging(WindowsBase.dll)来操作Office 2007/2010的文件格式,以至于大家都默许了.net 2.0下无法操作OOXML文件的观点,尽管也有人使用第三方zip类库来操作OOXML文件,但是遇到关系维护之类的问题,就开始纠结了,你必须自己去 不断地维护.rels文件(OOXML中用于维护文件内关系的文件,这里不是后缀名,这个文件就叫这个名字。),而且文件的内容越复杂,关系维护就越痛 苦。尽管微软出了OpenXml SDK 2.0,但是很遗憾,这套库也是基于.net 3.0的。当然,我倒不是.net 3.0的坚决反对者,只是出于部署方面的考虑,要知道目前基于.net 2.0的应用还是占据相当一部分份额的,尽管.net 3.0/3.5出来也3年了,但是相对于.net 2.0而言,只能算刚刚起步,这也是NPOI始终坚持.net 2.0版本为主线版本的原因。

有 人可能要说,.net 3.0/3.5不也是基于.net 2.0的吗?话是这么说,但是部署起来,还是要单独部署.net 3.0包,不是吗?相当于额外增加一套库,就拿我目前的公司来说,我们仍然在用vs2005开发,服务器上也只部署了.net 2.0 framework。

image

poi 中有一个库叫OpenXml4j,由Julien Chable于2008年捐赠给POI项目,主要负责OOXML基础操作,如创建、读取、修改、关系维护等。最近NPOI团队完成了OpenXml4j的 移植工作,于是就有了NPOI.OpenXml4Net,该组件将包括在NPOI下一个版本中,目前你可以通过googlecode的svn获得完整代 码,自行在本地编译。OpenXml4Net使用SharpZip作为底层zip操作库,而非Ionic.Zip,主要原因是SharpZip的设计与 java中的zip库更接近,移植相对简单,所以我们选择了这条捷径。不过有一点要向大家说明,OpenXml4Net仅负责底层操作,比如创建部件、创 建关系等,但不包括Office上层的功能,如创建xlsx文件、添加单元格等,这只是一个底层操作库,NPOI将在后续版本中陆续增加,Excel 2007, Word 2007, PowerPoint 2007对应的命名空间分别是NPOI.XSSF, NPOI.XWPF, NPOI.XLSF,NPOI.XSSF按计划将在半年内完成(预计在2012年6月或7月发布),这次随本文发布的算是社区预览版,你可以基于这个版本 给我们提建议和bug。

从头创建OOXML文件

任何一个OOXML都是一个zip文件,在本例中为了方便打开,我们直接使用.zip作为新建文件的扩展名。

//create ooxml file in memory
Package p = Package.Create();

//create package parts
PackagePartName pn1=new PackagePartName(new Uri("/a/abcd/e",UriKind.Relative),true);
if (!p.ContainPart(pn1))
    p.CreatePart(pn1, MediaTypeNames.Text.Plain);

PackagePartName pn2 = new PackagePartName(new Uri("/b/test.xml", UriKind.Relative), true);
if (!p.ContainPart(pn2))
    p.CreatePart(pn2, MediaTypeNames.Text.Xml);

//save file 
p.Save("test.zip");

//don't forget to close it
p.Close();

这里我们创建了2个部件,分别是位于/a/abcd目录下的e,和位于/b目录下的test.xml。这里有几点值得注意:

a. Package.Create有好几种调用方式,其中一种是上面这种Package.Create(),这样最直接的好处就是可以在内存中创建文件;而 Package.Create(path),即事先传入文件名,直接在文件系统上创建文件,不用MemoryStream。当然啦,对于大文件(超过 100M)以上的文件,使用Packakge.Create()做会占用较多的内存,所以如果并发量很高的话,建议慎用。

b. 用了p.ContainPart来判断节点是否已经存在,尽管对于新创建的文件这么做意义不大,但是这是个好习惯。

c. 创建PackagePartName的时候,Uri必须是Relative类型的,所以要传UriKind.Relative。这一点.Net做的比较 挫,默认Uri都是Absolute的,而且一旦Uri为Relative类型的,基本上调用任何Uri的属性全部会抛异常,这实现够坑爹的。

修改已存在的OOXML文件,并保存为新文件

修改已存在的文件也很简单,Package.Open就可以了,但由于最后要保存,务必传入PackageAccess.READ_WRITE,否则会抛异常。

//create ooxml file in memory
Package p = Package.Open("test.zip",PackageAccess.READ_WRITE);
//create package parts
PackagePartName pn3 = new PackagePartName(new Uri("/c.xml", UriKind.Relative), true);
if (!p.ContainPart(pn3))
    p.CreatePart(pn3, MediaTypeNames.Text.Xml);

//save file 
p.Save("test1.zip");

//don't forget to close it
p.Close();

对于已存在的文件,目前仍然有个bug,那就是不能直接保存为当前文件名,存在文件被占用的问题,我们将尝试在正式版中解决这个问题。

目前我们仍然在对OpenXml4Net接口进行调整,以提高组件的易用性和稳定性。如果大家发现啥bug或者问题,请直接通过邮件联系我。

下载NPOI.OpenXML4Net请到这里:http://code.google.com/p/npoi/downloads/list

OpenXML4Net的源代码请通过googlecode svn获取

[转载]Windows 下的 Nodejs

mikel阅读(1079)

[转载]Windows 下的 Nodejs.

本文为原创文章,出自http://cnodejs.org,转载请注明出处和作者
作者:We_Get
原文:http://cnodejs.org/blog/?p=5005

Windows 下的 Nodejs

为什么搞这个?

  1. 公司电脑的权限管理比较严,不能安装软件,不能常驻系统进程等,所以像 xampp 之类的都不能正常执行
  2. 我又想在空闲的时候做点东西
  3. 所以坑爹的我只能自己研究在windows下运行nodejs了

怎么执行?

  1. 下载并解压到一个目录
  2. 进入目录双击 Start.bat 执行
  3. 在命令行下执行node ex_project\jade\app.jse\app.js

你会看到

E:\nodejs4win>node ex_project\jade\app.js Express server listening on port 3000 in development mode 

这样的结果,那么打开浏览器输入:

http://127.0.0.1:3000/ 

OK,这样一个 nodejs + express + jade 的项目就跑起来了

所有 windows 都可以执行吗?

  1. 在 Windows Xp 下可以直接执行,不需要权限
  2. 在 Windows 7 下本地执行的话不需要 windows 权限,局域网内执行的话,需要开放局域网访问的权限。

都有什么?

  1. nodejs.exe — windows 版 nodejs
  2. npm — nodejs 的模板库管理工具,但windows下很多库都不能直接安装使用
  3. express — mvc framework
    1. jade — template
    2. dot — template
    3. ejs — template
    4. Tenjin — template
    5. jst — template ,有错误,还未修复
  4. dirty — 因为windows 下数据库还不支持,所以只能采用一些其他的工具替换了。这个是目前我找到的最好的工具了。
  5. n2Mvc — 国人开发的一个独立的轻型的mvc架构

怎么用?

  1. 刚接触nodejs的建议先从project 目录下的代码看起,从最简单的hello_world,到n2mvc,可以让你对Nodejs有一个初步的了解
  2. 然后可以在express的模板中选一套主攻吧

这套环境可以用来生产吗?

你开玩笑呢?哥,这个只是让你折腾玩的,想到生产环境还是用Linux吧,虽然我现在是做.net的,但我还是觉得windows不适合做服务器。

这些都是你写的吗?

不是,我只是把他们拼在一起。我会在后面给出他们的项目地址。

有文档可以参考吗?

  1. nodejs官方文档:http://nodejs.org/docs/latest/api/process.html#process.platform
  2. 国内社区的翻译版(未完成):http://cnodejs.org/cman/all.html
  3. nodecn 翻译的文档(未完成):http://www.nodecn.org/all.html
  4. Express JS 中文入门指引手册:http://www.csser.com/tools/express-js/express-guide-reference-zh-CN.html

有问题了问谁?

  1. 可以去cnodejs.org社区提问
  2. 可以去各项目主页发 Issues
  3. 也可以直接在我的项目主页留言等,我会尽量解答

项目【下载】地址

https://github.com/DrayChou/nodejs4win

引用到的项目地址

  1. nodejs : http://nodejs.org/
  2. express : https://github.com/visionmedia/express
  3. dirty : https://github.com/felixge/node-dirty
  4. n2Mvc : https://github.com/QLeelulu/n2Mvc
  5. jade : https://github.com/visionmedia/jade
  6. dot : https://github.com/olado/doT
  7. nTenjin : https://github.com/QLeelulu/nTenjin
  8. ejs : https://github.com/visionmedia/ejs
  9. jst : https://github.com/shaunlee/node-jst

[转载]豌豆荚逆向分析

mikel阅读(967)

[转载]豌豆荚逆向分析 – e@Board – 博客园.

最近玩手机应用,听说创新工厂有个豌豆荚,然后到官方往去下载,结果发现运行要求那里写着系统要求.net 2.0,一见到这个就高兴了,原来用.net做桌面应用的软件还是不少的,而且可能还可以逆向看部分代码。

装完豌豆荚,到安装目录里一看就看到几个关键的动态库了,其实豌豆荚用到了许多第三方开源库。就目前我知道的,有以下几个:

1.ffmpeg(http://ffmpeg.org/)大名鼎鼎的视频编码解码库,,豌豆荚在应该是用来做视频格式转换的,从几个dll的名称就可以看出

2.WebKit浏览器内核,豌豆荚是跟其它第三方应用市场合作的,基本上是通过web展示的,所以使用了WebKit的.net版本,具体可                    看http://github.com/webkitdotnet

3.用到了C#压缩组建 SharpZipLib,具体可以自行google

4.JavaScriptCore,JavaScript解析引擎,其实是WebKit的JavaScript引擎

5.Json.Net,就一Json的.net实现

接着对豌豆荚进行逆向,使用Reflector.exe逆向结果显示已经针对该工具加过壳,我一直从事.net应用程序的开发,对.net的保 护常识还是知道的,因为我们的软件也需要保护。Reflector.exe不行最多就是换个逆向工具嘛,使用ILSpy把豌豆荚一拖进去,源码自然全部就 出来了,结构如图

,只是由于使用了加壳和混淆工具,代码的一些核心都是使用一些奇怪的字符替换,要想分析经过混淆后的代码还是没那么容易的,只能通过代码逻辑来分析每个方法的作用了,至少可以看得到有些实现是什么做的。

本人只出于对于.net爱好的研究目的,做了简单的分析,也做一个警示,.net代码的保护不容忽视,在做开发时要学会保护软件。

[转载]SQLite的升级

mikel阅读(958)

[转载]SQLite的升级 – 熊猫82 – 博客园.

Android应用,不可避免的会与SQLite打交道。随着应用的不断升级,原有的数据库结构可能已经不再适应新的功能,这时候,就需要对SQLite数据库的结构进行升级了。

SQLite提供了ALTER TABLE命令,允许用户重命名或添加新的字段到已有表中,但是不能从表中删除字段。

并且只能在表的末尾添加字段,比如,为 Subscription添加两个字段:

1 ALTER TABLE Subscription ADD COLUMN Activation BLOB;
2 ALTER TABLE Subscription ADD COLUMN Key BLOB;

另外,如果遇到复杂的修改操作,比如在修改的同时,需要进行数据的转移,那么可以采取在一个事务中执行如下语句来实现修改表的需求。

1. 将表名改为临时表

ALTER TABLE Subscription RENAME TO __temp__Subscription;

2. 创建新表

CREATE TABLE Subscription (OrderId VARCHAR(32) PRIMARY KEY ,UserName VARCHAR(32) NOT NULL ,ProductId VARCHAR(16) NOT NULL);

3. 导入数据

INSERT INTO Subscription SELECT OrderId, “”, ProductId FROM __temp__Subscription;

或者

INSERT INTO Subscription() SELECT OrderId, “”, ProductId FROM __temp__Subscription;

* 注意 双引号”” 是用来补充原来不存在的数据的
4. 删除临时表

DROP TABLE __temp__Subscription;

通过以上四个步骤,就可以完成旧数据库结构向新数据库结构的迁移,并且其中还可以保证数据不会应为升级而流失。

当然,如果遇到减少字段的情况,也可以通过创建临时表的方式来实现。

[转载]技术宅---我的网上抢火车票攻略(终极秒杀版)

mikel阅读(1031)

[转载]技术宅—我的网上抢火车票攻略(终极秒杀版) – Phinecos(洞庭散人) – 博客园.

前几天在我在博客上发了一篇技术宅—我的网上抢火车票攻略,短短4天内点击量达到8000多,可见火车票是近期最为火热的话题了。这几天又帮很多朋友代购火车票,不断总结经验教训,最后得到了一个完整的全自动刷票方案。

准备工作:

1)一键自动刷票软件Go-Home

下载地址:http://code.google.com/p/go-home/ ,这个软件有多牛逼,看看下面的项目简介就知道了。。。

2) Firefox浏览器或者Chrome浏览器

3)   12306自动登陆脚本

https://gist.github.com/raw/1570973/f200dd587f6d68ab81edf74436b1fb7d91c79973/12306AutoLogin.user.js

4) 12306自动查询脚本,https://gist.github.com/raw/1554666/dec45c925002ec23ccef9f5be14770572d27625c/12306.user.js

关于这两个脚本如何使用,请参见《技术宅—我的网上抢火车票攻略》的后半部分,

5) 招商银行信用卡或一卡通

6) UCWeb手机浏览器

下面我们开始从头至尾进行一次快速 而完整的刷票之旅

第一步,使用一键刷票的Go-Home进 行全自动刷票,它会自动识别验证码,自动登陆,自动查询车票信息,自动选择最优车次及席别,自动订票,如果你时间充裕,建议改成非自动模式,采用人工输入 验证码相结合的方式进行刷票。这一步是至关重要的一步,同时也是最拼人品的一步,因为大家都知道,登陆和提交订单有多么困难。

第二步,如果你运气够好,在第一步中顺利地提交订单成功了,那么现在你要做的就是在45分钟内完成支付。这里我采用上面提到的12306自动登陆脚本,在FirefoxChrome中打开登陆页面,通过Ajax请求的方式可以避免刷新验证码图片的问题,从而可以用同一个验证码无限次尝试登陆,直至登陆成功。

第三步,如果你人品继续足够好,侥幸在firefoxChrome中登陆进系统了,那么恭喜你,赶紧进去最后一步支付吧。非IE用户无法使用网银,这个问题一直让人头痛,不过如果你有招商银行的信用卡或者一卡通,那么恭喜了,你可以无视这个问题了。当你选择使用招商银行进行支付时,非IE浏览器会打开手机支付的页面,输入你的卡号和手机号,它会将一个支付链接发到你的手机上,在手机上通过UCWeb浏览器打开这个链接,继续输入剩下的信息,就可以顺利完成支付了。

第四步,如果上帝继续眷顾你,让你顺利完成了支付,没有“支付超时“,没有“吞钱不吐票,那么这下真的要恭喜你了,你成功了!!!

Ok,就总结到这里了,这应该算是目前最强大的终极火车票秒杀版本了,感谢互联网上众多无私奉献的人们,你们提供的工具,脚本,让我们能有机会买到回家的车票,却分文不取,这种精神让人敬佩,而我这几篇文章就是向诸位致敬!!!