嗨,Scripting Guy!

嗨,Scripting Guy!

歡迎使用 TechNet 專欄,Microsoft Scripting Guy 會在此為您解答有關系統管理指令碼的常見問題。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。

還有,別忘了瞧瞧全新經過改良的《嗨,Scripting Guy!過往文件》。

今天的問題:如何得知安裝在電腦上的 .NET Framework 是哪一種版本?


如何得知安裝在電腦上的 .NET Framework 是哪一種版本?

嗨,Scripting Guy! 我要如何得知安裝在電腦上的 .NET Framework 是哪一種版本呢?

-- MW

MW,您好。常常有人對我們說:「你們每天都要寫一篇關於系統管理指令碼的專欄,一定很聰明嘍。」但願如此。其實啊,每天撰寫系統管理的專欄,就是因為我們聰明。最初撰寫這個專欄時 (說起來,寫專欄的週年紀念日就快到了),我們也以為很簡單:比方說,如果有人問我們:「如何在訊息方塊顯示資訊呢?」,我們只要寫好下面這個指令碼給他們:
Msgbox "Here is information in a message box."

剩下來的時間就可以拿來看棒球賽,兼玩網路撲克牌了。多美哪!

不過我們忘了一件事,以撰寫系統管理指令碼來說,Windows 雖然是一個好用的平台,但也不是沒有缺點。當然嘍,那些缺點也幾乎是每個人都會問到的。(難道沒有人想知道如何在訊息方塊顯示資訊嗎?)所以我們必須花大量時間研究各種問題,絞盡腦汁想出解決方案,當然還有努力工作了。而且就算沒有我們,世界撲克大賽還是會繼續進行的。

 

Scripting Guy 的意見。我們才不相信 ESPN 體育頻道會轉播世界撲克大賽呢,它也不可能轉播全國拼字比賽、X Game 還有其他等等的「仿運動」的運動 (我們對這些活動是沒什麼意見啦,只要別犧牲球賽或校際籃賽的轉播就行了)。當然,如果 ESPN 願意播放 Scripting Week 3,我們也樂意重新考慮我們的態度。請跟我們聯絡吧,ESPN。

編者的註解。以下是法律聲明:Scripting Guy 在此處發表的意見,並不代表 Microsoft Corporation 或 Microsoft 任何員工的意見。事實上,並非所有的 Scripting Guy 都同意「運動」的定義是什麼 (但是說真的,撲克和拼字能算是運動嗎?)


MW 對於 .NET Framework 的問題,確實反映出我們時常面對的困境。因為安裝在電腦上的.NET Framework 版本真的很重要,尤其當您在使用內部撰寫的自訂應用程式時更是。Scripting Guy 從痛苦的經驗得知,自訂應用程式常常會要求搭配特定版本的 NET Framework,早一點或晚一點的版本,一概都不接受。

也許您認為應該找得到一種又快又簡單的方法,可以判斷電腦上的 NET Framework 版本。告訴你吧,就算有,我們也找不到:我們永遠無法找到一個 COM 物件或是特定的登錄機碼告訴我們,電腦所安裝的是哪一個版本。頂多只能採用一種蠻力法,而且這個方法還附帶警告,詳細情形待會再為您解說。我們先看看下面這個指令碼:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\cimv2") Set colItems = objWMIService.ExecQuery("Select * from Win32_Product")

For Each objItem in colItems If InStr(objItem.Name, "Microsoft .NET Framework") > 0 Then Wscript.Echo objItem.Version End If Next

如您所見,指令碼本身很簡單。我們先連接到 WMI 服務,再以 ExecQuery 方法,擷取 Win32_Product 類別所有執行個體的集合。Win32_Product 是專門用來擷取所有利用 Windows Installer (亦即,.MSI 檔) 安裝在電腦上之軟體的相關資訊。Win32_Product 並非萬無一失,有時候也會漏掉一些的確以 Windows Installer 安裝在電腦上的應用程式。不過大部份的軟體程式 (包括 .NET Framework 在內) 它都能指認出來。

發出查詢之後,我們就設定一個 For Each 迴圈,循迴執行這個以 .MSI 檔安裝的軟體產品集合。在迴圈當中,我們利用下面這行程式碼以及 InStr 函數,檢查應用程式名稱是否含有 Microsoft .NET Framework 這個字串:

If InStr(objItem.Name, "Microsoft .NET Framework") > 0 Then


注意。我們稱它為蠻力法,是因為必須傳回所有安裝的軟體產品,而且必須辛苦檢查每一個名稱。我們大可使用 LIKE 運算子傳回名稱內含 Microsoft .NET Framework 字串的軟體。但是 IKE 運算子只有在 Windows XP 和 Windows Server 2003 才找得到。因此我們只能以蠻力法,讓指令碼在 Windows 2000 執行。


這個蠻力法很簡單,只要在 InStr 代入兩個參數即可:objItem.Name (含有應用程式名稱的變數) 以及目標字串 (Microsoft .NET Framework)。如果 objItem.Name 中不含這個目標字串,則 InStr 的傳回值為 0;如果含有目標字串,則 nStr 不為 0。說得確切一點,InStr 就是目標字串起始的字元位置。舉個例說,假設 objItem.Name 等於:

The Microsoft .NET Framework Version 2.0

則 InStr 等於 5,因為 Microsoft .NET Framework 字串是從第五個字元開始。如果 InStr 大於 0,我們便回應應用程式的 Version 屬性;換言之,我們會取得如下所示的資訊:

1.1.4322

當然,如果我們安裝了好幾個版本的 .NET Framework,則取得的版本號碼就不只一個。

這個方法確實很好用。那麼還有什麼問題呢?問題有兩個。一是速度可能有點慢:Win32_Product 類別是標準的慢郎中,不等 30 秒 (多半要看電腦上安裝了幾個應用程式而定) 恐怕很難取得資訊。更重要的一點是,Win32_Product 類別在預設情況下,並不會安裝在 Windows Server 2003。如果您要在 Windows 2003 機器執行指令碼,必須執行下列步驟:

  1. 在 [新增或移除程式] 中,按一下[新增/移除 Windows 元件]。
  2. 在 [Windows 元件精靈] 中,選取 [Management and Monitoring Tools],然後按一下 [詳細資料]。
  3. 在 [Management and Monitoring Tools] 對話方塊中,選取 [WMI Windows Installer 提供者],然後按一下 [確定]。

雖然有點麻煩,不過還是值得的。畢竟 Win32_Product 類別所能取得的資訊,絕不只是安裝在電腦上的 .NET Framework 版本而已。

對了,我們有沒有提過,我們是以下面這行程式碼在訊息方塊顯示資訊呢?

Wscript.Echo objItem.Version

同樣的,如果您是執行 CScript 的話,資訊就會顯示在命令視窗中,而不是訊息方塊中。所以嘍,也許沒人問我們「如何在訊息方塊顯示資訊?」這類問題,也不是什麼壞事吧。畢竟那可不像我們想的那麼簡單。


如需詳細資訊

請參閱嗨,Scripting Guy!- 過往文件

 

回到頁首 回到頁首