
欢迎来到本 TechNet 专栏,在这里,Microsoft 脚本专家将为您解答与系统管理脚本编写有关的各种常见问题。遇到了系统管理脚本编写方面的问题?请将电子邮件发送到 scripter@microsoft.com。我们不能保证回答收到的所有问题,但是我们将尽最大的努力。
同时,不要忘了查看您好,脚本专家!存档。
今日问题:如何将文本文件打印到默认打印机之外的打印机?
您好,脚本专家!如何将文本文件打印到默认打印机之外的打印机?
-- JD
您好,JD。伙计,谈谈骄兵必败吧。当我们开始着手回答此问题时,我们已经“知道”如何解决问题了。我们清楚地知道,Shell 对象为您提供了一种将文本文件打印到默认打印机的方法;我们还清楚地知道,该默认打印机是您能打印文本文件的唯一打印机。不过,作为脚本专家,我们认为我们对此问题有一个聪明的解决方法:我们会告诉每个人使用 Microsoft Word 来打印文本文件。然后我们会休息一下,倾听大家夸我们是多么的聪明。
天哪。只有当我们开始详细编写答案后,我们才真正地费神去检查并查看 Microsoft Word 是否确实允许您在通过脚本打印文档时选择其他打印机。事实证明,它不允许这样做:Word 也要求您打印到默认打印机。不得不承认,脚本专家错了。
注意:对,是这样的:我们错了许多次了。但这并不能减轻任何痛苦。 |
正如您所料,这就是骄傲:我们不得不寻找一种方法来将文本文件打印到其他打印机。遗憾的是,我们找不到这样一种方法。因此,我们决定采用第二种方案:如果我们只能打印到默认打印机,那么我们就只更改默认打印机,打印完文件后再改回来。以下为在 Windows XP 和 Windows Server 2003 下奏效的解决方案:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer Where Default = TRUE")
For Each objPrinter in colPrinters
strOldDefault = objPrinter.Name
strOldDefault = Replace(strOldDefault, "\", "\\")
Next
Set colPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer Where Name = '\\\\atl-ps-01\\printer2'")
For Each objPrinter in colPrinters
objPrinter.SetDefaultPrinter()
Next
Wscript.Sleep 2000
TargetFolder = "C:\Logs"
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(TargetFolder)
Set colItems = objFolder.Items
For Each objItem in colItems
objItem.InvokeVerbEx("Print")
Next
Set colPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer Where Name = '" & strOldDefault & "'")
For Each objPrinter in colPrinters
objPrinter.SetDefaultPrinter()
Next
注意:为何仅限于 Windows XP 和 Windows Server 2003 呢?是这样,之前的 Windows 版本不易识别和更改默认打印机;这是因为 WMI 类 Win32_Printer 既没有 Default 属性也没有 SetDefaultPrinter() 方法。因此,我们决定今天讨论 XP/2003 解决方案;如果您对 Windows 2000 版本有足够的兴趣,那好,我们来看看我们会得出什么样的结果。 |
不可否认,此脚本看起来可能稍微有点复杂;请宽容我们吧,尽管如此,您还是会看出我们要执行的操作以及为何执行这些操作的。我们首先连接到本地计算机上的 WMI 服务,然后检索默认打印机的 Name。这就是下面的代码所要执行的操作:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer Where Default = TRUE")
For Each objPrinter in colPrinters
strOldDefault = objPrinter.Name
strOldDefault = Replace(strOldDefault, "\", "\\")
Next
此段代码的第一部分应该很好理解;唯一稍难理解的部分在于我们的 WQL 查询。我们仅需要默认打印机的信息,因此我们构造了一个查询,该查询可返回 Default 属性等于 True 的打印机的数据。由于计算机上只能有一台默认打印机,因此,此查询应该只返回一台打印机。
代码段的第二部分(For Each 循环)可能需要多费一些口舌。在 For Each 循环中,我们检索默认打印机(请记住,该默认打印机是集合中的唯一打印机)的 Name 并将其存储在名为 strOldDefault 的变量中。至此不会有什么问题。接下来是下面这行代码:
strOldDefault = Replace(strOldDefault, "\", "\\")
为什么呢?是这样,如果默认打印机恰好为网络打印机,它将具有类似下面的名称:\\atl-ps-01\printer1。这并没有什么问题,只是稍后我们需要在脚本的 WQL Where 子句中使用该打印机名称。由于 \ 为保留字符,因此我们必须通过使用两个 \ 字符来“转义”每个 \ 字符;换句话说,我们的打印机(用于 Where 子句)的名称必须为 \\\\atl-ps-01\\printer1。我们使用 VBScript 的 Replace 函数来用一对 \ 替换打印机名称中的每个 \。
您清楚了吗?好的。接下来我们使用下面的代码块:
Set colPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer Where Name = '\\\\atl-ps-01\\printer2'")
For Each objPrinter in colPrinters
objPrinter.SetDefaultPrinter()
Next
Wscript.Sleep 2000
在此,我们将请求一个新的集合,该集合中包含名称为 \\\\atl-ps-01\\printer2(注意成对出现的 \)的所有打印机;正如您所料,这就是我们要进行打印的打印机。我们检索此集合(该集合将再次仅具有一个成员),然后使用 SetDefaultPrinter() 方法使 \\atl-ps-01\printer2 成为默认打印机。然后,我们将脚本暂停两秒钟,只是为了确保更改得以进行。
既然我们有了一个新的默认打印机,我们即可继续向下进行并打印我们的文本文件。我们已直接从“您好,脚本专家”专栏中引用了以下代码,即打印文本文件中的代码。在这,我们将不再讨论该代码;如果您需要了解详细信息,请参阅有关打印文本文件的专栏:
TargetFolder = "C:\Logs"
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(TargetFolder)
Set colItems = objFolder.Items
For Each objItem in colItems
objItem.InvokeVerbEx("Print")
Next
那么,到目前为止,我们都做了些什么呢?是这样,我们已确定了默认打印机的名称(对于此讨论,我们假定它为 \\atl-ps-01\printer1),并将其存储在了名为 strOldDefault 的变量中。我们已将默认打印机更改为 \\atl-ps-01\printer2 并打印了我们的文本文件。现在,我们必须要做的就是还原原来的默认打印机,我们使用下面的代码块来实现此操作:
Set colPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer Where Name = '" & strOldDefault & "'")
For Each objPrinter in colPrinters
objPrinter.SetDefaultPrinter()
Next
正如您所看到的,在此我们连接到了原来的默认打印机;即我们请求了一个集合,该集合包含了 Name 属性等于存储在变量 strOldDefault 中的值的所有打印机。获取该集合后,我们使用 SetDefaultPrinter() 方法将 \\atl-ps-01\printer1 重置为默认打印机。最终结果为:我们将我们的文本文件打印到了 printer2,而 printer1 仍为默认打印机。它可能不是特别聪明的解决方案,不过很有效。
而且,我们已经汲取了有关试图太过聪明的教训。我们承诺永远不再试图和真正地耍小聪明了(这是一条我们可能会信守的承诺)。
欢迎访问您好,脚本专家!- 存档