打印

[转帖] 到底是谁说脚本编写者无法访问 .NET Framework?

到底是谁说脚本编写者无法访问 .NET Framework?

美国内战期间(准确地说,是在 Spotsylvania 战役中),盟军将军 John Sedgwick 沮丧地发现这样一个事实:他的士兵被偶尔来自联邦狙击手的流弹吓得东躲西藏。据传,Sedgwick 曾这样对他的士兵说:“你们这样逃避,我真为你们感到羞耻。在这个距离,他们连一头大象也不可能击中。”过后不久,Sedgwick 即成为战争中被打死的官阶最高的盟军军官。也许在那个距离,联邦军狙击手无法击中一头大象,但不幸的是,对 Sedgwick 而言,他们却可以击中一位将军。
1 s, U% i- i U1 K# h毫无疑问,故事所传达的道理是(你已经提到了):“如果有人向你开枪,请把头低下”,这是一种很好的精神,不是吗?我们认为这是一种很不错的做法。我们还要提倡如下精神:“言词要谨慎,因为有一天它可能会回来,成为您的困扰。”对于 John Sedgwick 将军来说,这种情况真的发生了,对许多其他人也会如此。例如,人们记得 Thomas Watson,并不因为他曾是 IBM 的总裁,美国历史上伟大的企业家。而是因为他说过的这句话,“我认为全球大概只需要五台计算机就足够了。”8 @7 w+ K! R9 Y; l$ v0 P
有趣的是,并没有证据表明 Watson 确实说过这段话;充其量,他只是提到了其他人对这个问题的看法。但谁真正在意呢?毕竟,IBM 的总裁可能说过计算机没有市场,让我们得到一个深刻的教训,我们不能让貌似正确的愚蠢观点来妨碍我们,对吗?
9 `$ {5 f; f' y( a& n* [7 B顺便说一下,Watson 确实说过“迈向成功的最快方法,是把失败率提高一倍。”这是脚本专家们深信不疑的忠告。) p) |2 ^7 I( R: P! ~! j- X1 F
尤其是把失败率提高一倍的忠告。0 G( J# I" p& u+ k, o, m
接下来,是这段引用:“如果您正在编写 VBScript 脚本,那么您就无法访问 .NET Framework。”无可否认,与“在这个距离,他们连一头大象也不可能击中”或“我认为全球大概只需要五台计算机就足够了”相比,这段说明脚本专家无法访问 Microsoft® .NET Framework 的话不太容易让人记住,但是,这种说法同样是大错特错。.NET Framework 实际上是由 C# 和 Visual Basic® 语言的开发人员设计而成的,而且 VBScript 并不能实例化原生 .NET Framework 类。但这并不意味着脚本专家就无法访问 .NET Framework,至少可以访问其部分内容。
3 k$ C9 B5 ?) [9 a1 o2 G是的,您说对了:我们不能否认对于 VBScript 来说,大多数 .NET Framework 类是无法访问的。但是,也有相当大数量的 .NET 类具有可调用 COM 的包装程序,这就意味着这些类包含一个 COM 接口,使得脚本语言(如 VBScript)可以访问它们。您说这让人难以置信?那么看一看图 1 中显示的您注册表中的 HKEY_CLASSES_ROOT 部分;您应该能够看见随系统开始的所有类。
; O7 g& }' Z9 A4 i' B5 t3 c[url=javascript:ToggleImages('357510002', '357510002');]6 } @! {' K* Y# @: L

* \' ~- o' P9 Z w[/url]" ^: x- F0 ?3 K
图 1 注册表中的系统类 (单击该图像获得较小视图) 9 b8 z# c Q# Y5 I, g7 f1 k; U
[url=javascript:ToggleImages('357510002', '357510002');]# R5 p* C* D) Z7 k a: ~- w

$ J$ z! x* A( D3 r, c[/url]
* w6 {. E/ F D# L3 B& n图 1 注册表中的系统类 (单击该图像获得较大视图)
9 O3 z3 V2 |; s/ b6 E6 u这些多数是 .NET Framework 类,其中大部分都可以通过 VBScript 来实例化。7 V8 \1 F, b+ c, s7 a
我们曾在之前谈论过这一点!
% p% [ k4 n5 g- S/ x6 K当然,正如曾经购买过深夜电视广告产品的人所证实的一样,您可以做某事并不意味着就应该做(这是通常为什么某些商品没有现货的原因)。当然,您可以在脚本中创建 System.ContextMarshalException 类的实例,我们只是不知道您为什么要使用它或者如何使用它。
/ ?2 b1 O! D6 v8 D但并非所有 .NET Framework 类都是如此。例如,脚本编写领域中很让人困扰的一个问题,是没有一种简单的方法来对项目列表进行排序。要将列表按字母顺序排序,要求您使用未连接记录集或完全自行创建一个深奥的排序函数,如以下冒泡排序代码(不具备这种能力的人可能想要跳到下一段): 0 @& r7 }' _2 U7 J9 \$ Z
For i = (UBound(arrNames) - 1) to 0 Step -1$ `+ F1 [. z# C' }' o" m$ Q5 a
For j= 0 to i
* N6 L. G/ @ P: l If UCase(arrNames(j)) > ; b' ?- Y1 e; t! q
UCase(arrNames(j+1)) Then
}' W1 P# S* Y strHolder = arrNames(j+1): P0 r( j0 X' W! ~; [2 x, C
arrNames(j+1) = arrNames(j)/ f4 E/ Y" ~6 t4 P
arrNames(j) = strHolder
( g0 ?) C8 E, g* K3 Y. s. t1 c End If. q. j, w8 L) }3 k' q5 S; `
Next8 b# y) p1 J9 G% ^
Next" L' l2 C% ^. R7 E$ p# x, L0 K; ?& q
别灰心:我们编写了代码,但是我们也不完全确定它的意思。: Q# X9 c$ ], P, T
那么,在这种情况下,.NET Framework 如何来帮助我们呢?要回答这个问题,让我们看一小段非常简单明了的脚本:
( q* Q, `' Z' v/ I( d7 _' qSet DataList = CreateObject _
; \. e# V' A0 o/ J ("System.Collections.ArrayList")
7 f) Y! r$ T$ _. P7 G% kDataList.Add "B"8 K0 D8 s+ ~& g. t- {
DataList.Add "C" ?. r# ^9 Y8 B+ U
DataList.Add "E"/ j. [8 s$ t0 Y3 w
DataList.Add "D"
% m1 N; w, A. d kDataList.Add "A"
/ f2 J) d# h0 O6 M! qDataList.Sort()" \1 {& g& ]' W" X5 K) d; V% j
For Each strItem in DataList
2 k6 `6 N+ S9 h6 { Wscript.Echo strItem
! Z# A. s" M2 f- ^# |6 kNext
/ z) p+ h5 y% m' m0 @正如您所看到的,我们是在创建一个 .NET Framework 类 System.Collections.ArrayList 的实例。然后,我们使用 Add 方法向列表中添加五个项目。这的确不错,除了一点:我们以随机的方式(B、C、E、D、A)来添加这些项,但我们需要按字母顺序(A、B、C、D、E)来显示它们。该使用冒泡排序代码了,对吗?( t8 n6 k5 u8 x$ Y9 d& q
错了!(请原谅我们直言不讳,但是必须承认错误这个事实。)事实证明,我们不需要使用冒泡排序代码;我们所要做的是调用数组列表的 Sort 方法: d) j5 l3 k& B; S7 p/ L( T
DataList.Sort()
7 g/ _3 P) r8 |' O. a$ l就是这样。利用这一行代码,我们就可以对数组列表中的所有项进行排序。
! E! O- B: j& h/ F! [证明一下?哇,这么多人。没问题;我已经料到听众里会有一些人持怀疑态度。这就是为什么脚本会包括 For Each 循环的原因,它遍历列表中的所有项,将每项的值回显到屏幕上: 8 Q+ ]* a, ?, p6 e4 V! \" Q
For Each strItem in DataList7 V* ^* J! c' Q6 j& U8 P" B
Wscript.Echo strItem
0 S, G% T$ N, o' `; r% aNext6 v9 F/ V8 l ^4 F
现在,有一个问题需要你们解决:运行该脚本时,我们会得到什么返回结果?
, u6 x* ~* Z0 `2 ]猜得好: 7 t G% _$ {! ` ~
A
1 O) x' g; H( s/ Q; M% ^' a# ^: a9 ^B* U- F& Q% ]: D( E* z$ [& I
C' d) Q- j- ?; O( }( X
D' Z* @6 o/ h) i( M9 P' c' {- R; G
E
9 ]8 p5 ^" ?! L3 N( ~很不错,不是吗?# O1 d& Q9 M0 C# @7 t# m b, ]
嗯,我们看到你们中的一些人还不完全满意。你们都表示这很不错,但你们真正要做的是以降序回显这些值;即,需要一个从 Z 到 A 而不是从 A 到 Z 的列表。如果你们无法获得这种结果,那么……
4 ~& |9 Y( Y9 @" p嗨,没问题。你们只要提问即可:
3 V( }+ ^/ U. S0 r+ ^5 jSet DataList = CreateObject _
5 ~/ W0 [8 y5 H" R% R e ("System.Collections.ArrayList")9 O* S" o, V5 e+ @( f; f
DataList.Add "B"
' U% T& i# {* `DataList.Add "C"
4 \/ }' U1 f/ R; s1 bDataList.Add "E"$ f. E% H1 z+ H( y1 w
DataList.Add "D"+ O' g: B1 _5 i, v# W
DataList.Add "A"6 S% e- g% T6 p* J# I! p
DataList.Sort()
+ `0 R0 g( [* X- J* K. z! pDataList.Reverse()
) f4 j. U. I% E" w8 N" \For Each strItem in DataList- v: s9 x* _$ n& f
Wscript.Echo strItem
4 X% O" M) Y; o6 W jNext
( Q, U: u: e/ m1 L- \1 d你们说对了:这与我们刚才向你们展示的脚本非常相似,是吗?但是,有一个重要的补充。看一看我们在紧接着 Sort 方法的位置添加的单行代码: 4 E. m: `. R! \. w- ]5 s
DataList.Reverse()7 i. ?( F/ G; ?- m% i
看到了吗?在对列表进行升序排列后,我们调用 Reverse 方法,该方法将数组中的所有项逆序排列,这简直令人难以置信。它提供给我们什么?它提供给我们如下所示的输出:
6 l9 @/ U" k9 S) N8 u1 m, BE
% R* o5 d4 T. ~D( q: K' S% b7 W2 O- Y
C4 q9 p, ~* e5 {
B
* `. G: m v5 g# h7 _+ g+ fA! h) d# t$ d' S( A1 r7 u; D
这真得让人为之一振,不是吗?9 `8 j$ S" B2 A" }: L$ `) |, m' a1 }
但是等等!我们还能做得更好。你们尝试过从 VBScript 数组中删除一项吗?不要大声喧哗;我们不打算要你们这么做。我们将向你们展示从 .NET Framework 数组列表中删除一个项目是多么容易。不喜欢字母 D?去掉它。以下是创建数组列表、对其进行排序然后删除条目 D 的脚本:
' I: k i4 M8 O. k& l( L8 e" lSet DataList = CreateObject _
+ d# `7 c p2 r" _! ~' z ("System.Collections.ArrayList")( ]+ O7 Q- |% Z7 G$ V
DataList.Add "B"; M7 a. x$ X' L1 X
DataList.Add "C". Q" o% b* `( S" T4 r5 J
DataList.Add "E"" g W7 j9 z1 ?7 v; [& z
DataList.Add "D"
! e8 \& m8 N2 j$ V" ~' o2 Z4 EDataList.Add "A"+ |! q7 O7 `. F; I$ Y
DataList.Sort()
0 _9 V* C+ t! M. mDataList.Remove("D")! `+ m& d( t% r4 Z3 a: N# g
For Each strItem in DataList
+ B! t! x; O s& z5 \' K/ b; N Wscript.Echo strItem/ j) ?, D1 x& Z* o: P
Next
: [2 ?" \( \2 V" Q, C你们应该再次看看紧接在 Sort 方法后的小行代码: * c4 h4 G8 A, Y- E( `
DataList.Remove("D")
) h) ~, D( j- }此处我们使用了 Remove 方法来删除等于 D 的项。以下是运行脚本时获得的返回结果:
2 K1 Q5 E2 |( A) h2 r7 V( IA
$ p; U* C. W: [. [1 MB3 [3 h$ q( i W! h
C9 U( P4 n1 Y/ F
E
. \: t6 V/ |4 o- Y/ q8 N再见,D!
9 ^# l: Y7 d5 S并且不要忽略了最精彩的一点:我们可以在不必调整数组大小或重新设置其维数的情况下删除项目。这很酷。当然,我们也可以不必调整数组大小或重新设置其维数就向数组添加项。还有什么地方没让您的脚本编写更加简单快捷呢?
% \& K i$ d; K/ H/ ^信不信由你,这里只涉及了你们可以对 .NET Framework 数组列表所做的一小部分操作(有关详细信息,请参阅
0 @% [- d8 A# S.NET Framework SDK 中的数组列表条目
4 Y% t0 D4 d" D+ K) U)。3 t+ h }( \2 M
数组列表对脚本程序有用吗?让我们这样来解释一下:看过 .NET Framework 数组列表后,我们不清楚你们为什么要使用内置 VBScript 数组,至少不应用于我们在此处使用过的简单项目列表。0 q; K8 T. j" D' Y' O
无可否认,我们脚本专家没有对 .NET Framework 做详尽的调查以了解哪些类可能对脚本程序有用(以及哪些可能没有用)。这项工作正在进行之中。同时,请随意浏览整个 + h5 I6 W6 l( N' r
.NET Framework SDK
- ^" n. s `; p" l5 \8 S7 o。似乎每次浏览 SDK 时,我们都能发现一些有趣的新东西可供脚本编写者使用。
+ c& D2 \! u( m5 ?/ \- Y举个例子?生成随机数怎么样?要使用 VBScript 随机数生成器生成一个 1 到 100 之间的随机数吗?没问题,只需使用类似以下的代码:
: `" j' {# c* DRandomize
: o. t5 C9 l2 H4 F; hWscript.Echo Int((100 - 1 + 1) * Rnd + 1)
- C( n3 G$ _6 Q& a u+ A9 V记住那个公式了吗?如果没有,别担心;事实证明,使用 .NET Framework System.Random 类要简单直观得多: . a/ @% M3 s8 n( P! y, g# `6 J
Set objRandom = CreateObject("System.Random")
* S" q7 n9 b& k& {! P% BWscript.Echo objRandom.Next_2(1,100)
. w: G! k3 C* S: |, I你们很可能不需要解释说明就能计算出结果。无论怎样,我们将提供给你们一个简短的说明,只因为 TechNet 杂志认为专栏作家每个月应该实际写些东西。(如果非得问个为什么,那我只能说这是他们的策略,不是我们的。)
! k/ f+ `; [6 Y, T) |& w正如您所看到的,我们创建了一个 System.Random 的实例,然后传递两个参数来调用 Next_2 方法: # F \9 s/ h* F4 V; o4 B6 I
1,范围内的第一个数(记住,我们希望生成一个 1 到 100 之间的随机数)。
8 ^. E) W/ |/ k9 b0 t! ^; e100,范围内的上限数。1 ]+ W6 d S* \ u6 X2 P2 n9 s
这就是我们所要做的一切。
0 G( i6 c' X7 m1 t7 l* d6 j) ]' U8 l3 R似乎我们还有时间来回答最后一个问题。穿绿衬衫的这位。到底是谁说脚本编写者无法访问 .NET Framework?这个,坦白地讲,我们刚开始的时候 – 天哪,好象时间已经到了。下个月见!
《无量寿经·第十八愿》言:
设我得佛,十方众生,至心信乐,欲生我国,乃至十念,若不生者,不取正觉。唯除五逆,诽谤正法。

TOP