Office Space:撰寫 Microsoft Office 應用程式指令碼的秘訣

Office Space

歡迎蒞臨 Office Space 專欄,這裡提供處理 Microsoft® Office 應用程式指令碼的秘訣。每週二和週四我們將刊出新的秘訣,若要參閱以前討論過的秘訣,請造訪 Office Space Archive (Office Space 過往文件)。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。

不管 Microsoft Outlook 是否正在執行都啟動指令碼

假設您從電腦商家那買了一台 DVD 光碟機,而安裝指示就這麼一行:

「安裝光碟機後,請裝回電腦面蓋」。

要是您已經安裝好 DVD 光碟機的話,這指示還蠻貼心的。萬一您還沒安裝 DVD 光碟機呢?那份安裝指示是一點用也沒有。您可能會開始臭罵 DVD 製造商,這不怪您。如果參考文件假設您已經執行特定步驟,而您不巧還沒有執行這些步驟,那參考文件其實沒有任何用處。

我們 Scripting Guys 在面對不實際的假設時,是否還得繼續寫程式?當然不敢,嗯,儘量避免啦。有時候我們寫程式時,的確得大膽假設。舉一個現成的例子:每次我們撰寫有關 Microsoft Outlook 的指令碼時,總會順帶一提:

「這個指令碼中假設 Microsoft Outlook 目前正在執行。」

如果您已經執行 Microsoft Outlook,這項提醒還挺貼心的。那萬一沒有呢?那指令碼是不是就沒用了?難道 Microsoft Scripting Guys 就跟 DVD 製造商一樣不負責任嗎?

這就戳到我們的痛處 (雖然我們知道主管會怎麼回答)。但至少 Scripting Guys 倒是不怕承認我們有時候的確是有點疏忽。今天要向您示範怎麼用指令碼檢查 Outlook 是否正在執行。如果是,指令碼會與 Outlook 現有的執行個體繫結,並回報 [收件匣] 內的項目數。(看似沒事做,但其實是一種透過找事做來判斷指令碼是否執行的方法。)如果 Outlook 沒執行,則指令碼會啟動 Outlook 並回報 [收件匣] 內的項目數。只要學會這招,從今以後執行指令碼前您再也不用擔心 Outlook 還沒執行了,保證有效。

注意:為何要大費周章學這些呢?這主要是因為有登出 Outlook 的需要,如果 Outlook 已經在執行,您只需要建立 Outlook.Application 物件的執行個體來繫結應用程式。但如果 Outlook 尚未執行,則必須呼叫 Logon 方法並登入 Outlook,指令碼才能執行後續動作。

有人或許會問:「乾脆想辦法在 Outlook 不執行的情況下,永遠登入 Outlook 不就得了?」是可以,但最好不要這樣做。萬一 Outlook 已經在執行了,另外建立和登入 Outlook 會造成兩個一樣的應用程式同時執行,而且這兩個應用程式會執行同一個 outlook.exe 程序。一旦指令碼跑完並關閉 Outlook,兩個執行個體都會不見。我想您已經給弄糊塗了,簡單說,使用一個 Outlook 執行個體比較簡單。


我們的指令碼這樣寫,後面有更多說明:


Const olFolderInbox = 6

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_Process Where Name = 'outlook.exe'")

If colItems.Count = 0 Then
    Set objOutlook = CreateObject("Outlook.Application")
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    objNamespace.Logon "Default Outlook Profile",, False, True    
    Set objFolder = objNamespace.GetDefaultFolder(olFolderInbox)
    objFolder.Display
    Set colItems = objFolder.Items
    Wscript.Echo colItems.Count
Else
    Set objOutlook = CreateObject("Outlook.Application")
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objFolder = objNamespace.GetDefaultFolder(olFolderInbox)
    Set colItems = objFolder.Items
    Wscript.Echo colItems.Count
End If


指令碼一開始定義一個叫做 olFolderInbox 的常數,值設為 6,稍後我們會用這來指示指令碼連結並顯示 [收件匣] 。接著我們來使用一些經典的 WMI 程式碼來傳回本機電腦上目前執行的所有處理序集合,或至少可執行檔名 outlook.exe 裡的所有處理序,藉此判斷 Outlook 是否正在執行:如果找到名為 outlook.exe 的處理序,表示 Microsoft Outlook 正在執行。如果沒有,則表示 Outlook 目前不在執行狀態。

那要該如何判斷是否有找到名為 outlook.exe 的處理序呢?很簡單,所有 WMI 集合都包含 Count 屬性名稱,名符其實,Count 可以顯示集合裡頭的項目數。如果 Count 等於 0,表示目前沒有執行任何名為 outlook.exe 的處理序;不等於 0,則表示名為 outlook.exe 的處理序正在執行。

有沒有可能 Count 等於 0 但是 Outlook 沒有執行呢?為了防止這種情況,我們需要跑下面這段指令碼:


Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
objNamespace.Logon "Default Outlook Profile",, False, True    
Set objFolder = objNamespace.GetDefaultFolder(olFolderInbox)
objFolder.Display
Set colItems = objFolder.Items
Wscript.Echo colItems.Count


指令碼一開始建立 Otloook.Application 物件的執行個體,然後使用 GetNamespace 方法連接到 MAPI 命名空間 (這是我們唯一能連接的命名空間)。接著呼叫 Logon 方法,確認能連接到適當的 Outlook 設定檔。Logon 方法需要用到四個參數:

參數

說明

Profile

要連接的 Outlook 設定檔名稱。這個範例指令碼使用「Default Outlook Profile」。

Password

連接時可用的選用密碼。這個參數主要在於提供舊版相容性,通常是留白。

ShowDialog

用來指定是否要顯示設定檔選取對話方塊。因為已經指定使用「Default Outlook Profile」,所以不需要顯示這個對話方塊,因此值設定為 False。

NewSession

用來指定是否要建立新的 Outlook 工作階段。因為 Outlook 目前並未執行,當然需要建立新的工作階段。因此這個參數設為 True。


連接正確的設定檔後,我們要用 GetDefaultFolder 方法繫結至 [收件匣],接著呼叫 Display 方法在螢幕上顯示應用程式。請注意,這和其他 Office 應用程式不同。例如,使用 Word 或 Excel 時,您可以建立 Application 物件的執行個體,然後把 Visible 屬性設為 True。但 Outlook 的運作方式不一樣,這裡必須先繫結至命名空間和資料夾,然後呼叫 Display 方法,才能看見資料夾和整個 Outlook。

接下來,我們用這兩行指令碼傳回 [收件匣] 裡頭所有的項目集合,然後傳回 Count 屬性的值,藉此判斷集合裡有多少項目:


Set colItems = objFolder.Items
Wscript.Echo colItems.Count


這樣就得了。判斷出 Outlook 並非執行後,啟動並登入 OUtlook,方法其實不難。

那如果 Outlook 的確在執行中,該怎麼辦?沒問題,只要改執行以下這段指令碼即可:


Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderInbox)
Set colItems = objFolder.Items
Wscript.Echo colItems.Count


這兩段指令碼只有兩個不同之處:第一,不需要使用 Logon 方法登入 Outlook,因為我們已經登入了。第二,不需要使用 Display 方法來顯示 Outlook,因為很可能 Outlook 已經出現在畫面上。就這樣,剩下來的指令碼完全一樣。

好啦!您現在已經有指令碼,不管 Outlook 是否正在執行都可以使用。不好意思,雖然好用,但是對安裝 DVD 光碟機還是幫不上忙。往好處想想,至少您現在可以連上 Outlook 寫信給製造商抱怨他們一下。

顯示: