Script real com o Microsoft Office

Crie o seu próprio gerenciador de tarefas usando o Microsoft Word (não, realmente)

Quando você comprou a sua cópia do Microsoft Office, provavelmente sabia que estava adquirindo um conjunto de aplicativos de classe mundial, tudo de uma planilha para um processador de texto de um cliente de email. O que você não devia saber é que também estava obtendo a resposta para uma pergunta que aborreceu os escritores de script por anos: como recuperar uma lista de todos os aplicativos e janelas abertas sendo executados em um computador?

Lembre-se de que não estamos falando sobre como obter uma lista de todos os processos sendo executados em um computador. Se você deseja esses dados, pode usar a classe Win32_Process do WMI. Se solicitarmos a classe Win32_Process para recuperar os nomes de todos os processos sendo executados em um computador, receberemos informações semelhantes a esta:

Dd569891.tasks1_sm(pt-br,TechNet.10).jpg

Não há nada de errado com esta informação. Na verdade, freqüentemente você desejará um conjunto completo de todos os processos sendo executados em um computador. Entretanto, em outras vezes, somente desejará a lista de itens encontrada na guia Aplicativos no Gerenciador de Tarefas:

Dd569891.tasks2_sm(pt-br,TechNet.10).jpg

Em outras palavras, você deseja apenas as janelas abertas e gostaria de receber nomes amigáveis em oposição aos nomes de arquivo executáveis (como Portable Script Center em vez de hh.exe). Mas o WMI não permite que você obtenha essas informações e nenhum outro objeto de script interno do sistema operacional. (O objeto Shell fornece uma maneira para listar todos os itens de shell abertos em um computador.)

Surpreendentemente, o Microsoft Office pode obter estas informações para você. O objeto Application do Microsoft Word inclui uma propriedade Tasks que retorna uma coleção de todos os processos que estão sendo executados em um computador. Uma diferença entre essa e a Win32_Process é o fato de que a coleção Tasks retorna nomes amigáveis para esses processos em vez de nomes de arquivo executáveis. Deste modo, você obtém informações como estas:

Dd569891.tasks3_sm(pt-br,TechNet.10).jpg

Mas espere: há pelo menos uma diferença entre o objeto Task que representa processos individuais na coleção Tasks e os objetos retornados por Win32_Process. Conforme escrevemos neste artigo, tínhamos 46 processos sendo executados no computador. No entanto, somente 11 itens foram exibidos na guia Aplicativos do Gerenciador de Tarefas. Isso porque a maioria desses processos, incluindo a maioria dos serviços, foi executado em uma janela oculta. É assim que o Gerenciador de Tarefas determina os processos que são exibidos na guia Aplicativos. Se você puder ver a janela na qual o processo está sendo executado, um aplicativo será mostrado depois. Se você não conseguir ver a janela, o aplicativo não será mostrado.

Observação. Mais tarde, nós mostraremos a você um script que retorna nomes amigáveis para todos os processos que estão sendo executados no computador. É difícil examinar os nomes de arquivo executáveis e não ter nenhuma idéia do que realmente está sendo executado em sua máquina. Os nomes amigáveis proporcionam a você uma imagem muito mais clara.

A classe Win32_Process não tem como saber se um processo está sendo executado em uma janela oculta ou não. Por isso, não é possível identificar os processos que o Gerenciador de Tarefas marca como aplicativos. Entretanto, o objeto Task inclui a propriedade Visible que indica se o processo está sendo executado em uma janela visível ou não. Podemos nos beneficiar da propriedade Visible para identificar janelas e aplicativos abertos.

Na verdade, vamos examinar um script que faz isso:

Set objWord = CreateObject("Word.Application")
Set colTasks = objWord.Tasks

For Each objTask in colTasks
    If objTask.Visible Then
        Wscript.Echo objTask.Name
    End If
Next

objWord.Quit

Começamos criando uma instância do Microsoft Word. Depois de guardarmos a coleção Tasks em uma variável chamada colTasks, configuramos um loop For Each para treinar a coleção. Para cada tarefa individual (isto é, para cada processo que está sendo executado no computador) verificamos se o processo está sendo executado em uma janela visível. É isso que esta linha de código faz:

If objTask.Visible Then

Se a propriedade Visible for True, exibimos o nome da tarefa. Se a propriedade Visible for False (significando que o processo está sendo executado em uma janela oculta), efetuamos um loop e examinamos a próxima tarefa na coleção. Depois passarmos por toda a coleção, encerramos o Word e os scripts são finalizados.

Qual é o resultado final? Bem, o resultado final é que recebemos uma lista quase idêntica à lista encontrada na guia Aplicativos do Gerenciador de Tarefas. A única diferença é que o Gerenciador de Programas – que, começando com o Windows 98, realmente se refere ao menu Iniciar – é exibido em nosso resultado do script, mas não é exibido no Gerenciador de Tarefas. Junto com as linhas semelhantes, o Gerenciador de Tarefas não é exibido na guia Aplicativos do gerenciador de Tarefas, embora seja exibido no nosso resultado do script.

Dd569891.tasks4_sm(pt-br,TechNet.10).jpg

Isso é legal ou o quê? Se desejássemos obter uma lista de todos os processos, independentemente do fato de eles serem visíveis ou não, poderíamos usar um script como este:

Set objWord = CreateObject("Word.Application")
Set colTasks = objWord.Tasks

For Each objTask in colTasks
    Wscript.Echo objTask.Name
Next

objWord.Quit

Mais isso ainda não é nem a metade. Deseja saber se alguém está jogando Paciência no computador? Então use o método Exists para verificar se Paciência é exibido na coleção Tarefas:

Set objWord = CreateObject("Word.Application")
Set colTasks = objWord.Tasks

If colTasks.Exists("Solitaire") Then
    Wscript.Echo "Someone is playing Solitaire."
End If

objWord.Quit

Se você preferir que eles não joguem Paciência, bem, use o método Close para desligar o jogo:

Set objWord = CreateObject("Word.Application")
Set colTasks = objWord.Tasks

If colTasks.Exists("Solitaire") Then
    colTasks("Solitaire").Close
End If

objWord.Quit

De forma alternativa, você poderia ajudar a pessoa exibindo o jogo Paciência e maximizando-o. Isso pode ser feito primeiro ativando a janela (usando o método Activate) e, em seguida, definindo a propriedade WindowState como wdWindowStateMaximize (uma constante que definimos e atribuímos a ela o valor 1). Por exemplo:

Const wdWindowStateMaximize = 1

Set objWord = CreateObject("Word.Application")
Set colTasks = objWord.Tasks

If colTasks.Exists("Solitaire") Then
    colTasks("Solitaire").Activate
    colTasks("Solitaire").WindowState = wdWindowStateMaximize
End If

objWord.Quit

Se você preferir minimizar a janela, atribua o valor 2 à constante wdWindowStateMaximize.

Enquanto você estiver nesse ponto, o objeto Task também permite que você acesse algumas outras propriedades de janela, incluindo Height, Width, Top (a posição vertical da janela medida em pontos) e Left (a posição horizontal da janela medida em pontos). Assim, você precisaria escrever um script semelhante a este:

Set objWord = CreateObject("Word.Application")
Set colTasks = objWord.Tasks

If colTasks.Exists("Solitaire") Then
    Wscript.Echo "Name: " & colTasks("Solitaire").Name
    Wscript.Echo "Top: " & colTasks("Solitaire").Top
    Wscript.Echo "Left: " & colTasks("Solitaire").Left
    Wscript.Echo "Height: " & colTasks("Solitaire").Height
    Wscript.Echo "Width: " & colTasks("Solitaire").Width
End If

objWord.Quit

Que retorna dados semelhantes a estes:

Name: Solitaire
Top: 65
Left: 50
Height: 329
Width: 445

E todo esse tempo você pensou que o Word servia apenas para escrever memorandos. Ei, quando a Microsoft diz que o Word pode fazer tudo, ela realmente quer dizer isso!

É claro que devemos destacar que a coleção Tasks no Word pode complementar a classe Win32_Process, mas definitivamente não assume a posição da Win32_Process. Isso porque a Win32_Process retorna uma tonelada de informações – tempo de modo de kernel, tempo de modo de usuário, identificação do processo, contagem de identificadores – que a coleção Tasks não pode retornar. Além disso, não vemos uma maneira óbvia de vincular um programa recuperado pela coleção Tasks ao seu processo correspondente na classe Win32_Process. Se e quando conseguirmos, informaremos a você.