我正在尝试将PDF打印为XPS,该脚本打开PDF Print Output As
屏幕并输入正确的名称,然后将ENTER
命令发送到窗口以保存文件。
如何选择地址栏以输入所需的路径?或者我该如何更改默认保存路径?
编辑:感谢您的反馈。这是脚本:function print_files($secure_pdf_dir){
#Retrieves the name for the .xps files
Get-ChildItem $secure_pdf_dir -Filter *.pdf -Recurse | Foreach-Object {
#For each .pdf file in that directory, continue
same_time $_.FullName
}
}
## The following function keeps checking for a new window called "Save Print Output As"
## When the window shows up, it enters the name of the file and press ENTER
function enter_my_names($xps_dir, $fullname){
$wshell = New-Object -ComObject wscript.shell;
while($wshell.AppActivate('Save Print Output As') -ne $true){
$wshell.AppActivate('Save Print Output As')
}
$basename = [io.path]::GetFileNameWithoutExtension($fullname)
#This is where the name is actually entered
$wshell.SendKeys($xps_dir\$basename)
$wshell.SendKeys("{ENTER}")
}
## The following function launches simultaneously a print job on the input file
## and a function waiting for the print job to show up to name the file
workflow same_time{
Param(
$fullname
)
parallel{
Start-Process -FilePath $fullname –Verb Print -PassThru
enter_my_names $xps_dir $fullname
}
}
#MAIN PROGRAM
#Here the script saves your current printer as default
$defprinter = Get-WmiObject -Query "Select * from Win32_Printer Where Default=$true"
#Queries for a XPS printer
$printer = Get-WmiObject -Query "Select * from Win32_Printer Where Name='Microsoft XPS Document Writer'"
#Sets the XPS printer as Default
$printer.SetDefaultPrinter()
#Starts the main job
print_files($secure_pdf_dir)
#Sets the old default printer back as default again
$defprinter.SetDefaultPrinter()
#This is a small delay to be sure everything is completed before closing Adobe Reader. You can probably shorten it a bit
sleep 2
#Finally, close Adobe Reader
Get-Process "acrord32" | Stop-Process
似乎$xps_dir
变量未正确传递给函数。
编辑:尝试将$ xps_dir添加到enter_my_names函数时出错:
Microsoft.PowerShell.Utility\Write-Error : Cannot validate argument on parameter
'FilePath'. The argument is null or empty. Provide an argument that is not null or
empty, and then try the command again.
At same_time:115 char:115
+
+ CategoryInfo : NotSpecified: (:) [Write-Error], ParameterBindingValidati
onException
+ FullyQualifiedErrorId : System.Management.Automation.ParameterBindingValidationEx
ception,Microsoft.PowerShell.Commands.WriteErrorCommand
+ PSComputerName : [localhost]
答案 0 :(得分:0)
文件对话框将接受文件名字段中的路径,因此不会发送文件名file.pdf
而是发送文件的完整路径C:\folder\folder\file.pdf
修改强>
您可以像这样发送文件夹路径:
$wshell.SendKeys($xps_dir)
$wshell.SendKeys("{ENTER}")
$wshell.SendKeys($basename)
$wshell.SendKeys("{ENTER}")
答案 1 :(得分:0)
将包含所需目录的变量(在本例中为$ xps_dir)传递给流程中的每个函数,直到它到达enter_my_names
函数,然后可以使用$wshell.SendKeys("$xps_dir\$basename")
将其发送到窗口。
function print_files($xps_dir, $secure_pdf_dir){
#Retrieves the name for the .xps files
Get-ChildItem $secure_pdf_dir -Filter *.pdf -Recurse | Foreach-Object {
#For each .pdf file in that directory, continue
same_time $xps_dir $_.FullName
}
}
## The following function keeps checking for a new window called "Save Print Output As"
## When the window shows up, it enters the name of the file and press ENTER
function enter_my_names{
param ($xps_dir, $fullname)
$wshell = New-Object -ComObject wscript.shell;
while($wshell.AppActivate('Save Print Output As') -ne $true){
$wshell.AppActivate('Save Print Output As')
}
$basename = [io.path]::GetFileNameWithoutExtension($fullname)
#This is where the name is actually entered
$wshell.SendKeys("$xps_dir\$basename")
$wshell.SendKeys("{ENTER}")
}
## The following function launches simultaneously a print job on the input file
## and a function waiting for the print job to show up to name the file
workflow same_time{
Param(
$xps_dir, $fullname
)
parallel{
Start-Process -FilePath $fullname –Verb Print -PassThru
enter_my_names $xps_dir $fullname
}
}
#MAIN PROGRAM
#Here the script saves your current printer as default
$defprinter = Get-WmiObject -Query "Select * from Win32_Printer Where Default=$true"
#Queries for a XPS printer
$printer = Get-WmiObject -Query "Select * from Win32_Printer Where Name='Microsoft XPS Document Writer'"
#Sets the XPS printer as Default
$printer.SetDefaultPrinter()
#Starts the main job
print_files $xps_dir $secure_pdf_dir
#Sets the old default printer back as default again
$defprinter.SetDefaultPrinter()
#This is a small delay to be sure everything is completed before closing Adobe Reader. You can probably shorten it a bit
sleep 2
#Finally, close Adobe Reader
Get-Process "acrord32" | Stop-Process
答案 2 :(得分:0)
我不确定您是否能完全解决这个问题,或者我误读了您的帖子,但是我能够从您最初的帖子中实现一些代码来完成我的项目[[以非传统的方式撞墙而过比较科学人];因此,我想分享一些我希望能对您有所帮助的事情(以防您仍然处于十字路口)。
一些景点: -我的整个流程是批量报告生成器。可变数量的.XML样式表发送到IE,因为javascript子例程为报告编号;为实现此目的,我使用Visual Basic进行了一些数据库解析,将值传递到形成.XML样式表所需的自定义脚本中,然后VB使用创建IE com对象所需的各种PS命令创建PS .ps1文件。最后,VB调用.ps1脚本,然后通过将样式表发送到IE,等待HTML渲染,发送打印命令并关闭对象来生成报告。
-您的最终目标是生成XPS,而我的目标是完全呈现HTML,然后使用PDF打印机进行打印;我假设我们有一个类似的过程,因为我们必须在中间阶段使用一个对话框(在这种情况下,使用sendkey与之交互);这是我将在下面专门讨论的内容,希望能对您有所帮助!
因此,有两点讨论:
“ $ xps_dir” |外文件-FilePath“ C:\ somefolder \ sometext.txt”-追加
文本文件本身不需要存在,但文件确实存在...上面的命令将创建文本文件。
此外,如果您可以查看Powershell提示,可以使用WRITE-HOST。
无论哪种方式,我都想知道最终的编译字符串是否编译不正确,因此无法将其识别为目录。
首先,我尝试发送文件名,然后发送回车。我认为这很好,因为在手动交互过程中,“另存为”对话框的焦点移到了“文件名”字段。但是,尝试之后:
$ wshell.SendKeys($ myfilename) $ wshell.SendKeys(“ {ENTER}”)
我意识到SendKeys命令正在将密钥发送到“保存位置”下拉菜单(或者可能是“另存为”对话框的第一个元素)。因此,我手动单击“保存位置”字段中的内容,然后依次进行制表,直到获得1.“文件名”(写下标签数)和2.“保存”按钮(写下标签数)。 )。通过添加SendKeys(“ {TAB}”)来与我观察到的选项卡数量相对应,我能够成功输入我的姓名字符串并关闭打印对话框:
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{TAB}")
$wshell.SendKeys($myfilename)
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{ENTER}")
注意:对话框中选项卡的数量可能会有所不同,因此我强烈建议您手动进行一次遍历,以计算有多少选项卡将您带到您要与之交互的字段。
总而言之,我需要考虑一下:
我已经(非常成功)使用VB和PS使用html元素来动态增强我的例程。由于我们能够将对话框设置为Com对象,因此我的下一个目标是尝试利用各自的“元素”,类似于访问html元素的方式(或更普遍地,面向对象的语言允许) 。这样,我也许可以更好地与对话框进行交互,而不会遭受SendKeys的缺点:
此外,我还没有完成有关错误窗口的任何工作,但是我已经注意到的一个问题是“您的文档名称相同等等”,所以请注意。
即使我们正在做两种不同的事情,这还是例程的这一部分的最终代码,以防它有助于提供上下文:
#send command to internet explorer application with execWB; 6 for print, 2 for no user prompt on window
while ( $ie.busy ) { Start-Sleep -second 3 }
$ie.execWB(6,2)
#create dialog box object
$wshell = New-Object -ComObject wscript.shell;
while($wshell.AppActivate('Save As') -ne $true){ Start-Sleep -second 3 }{
$wshell.AppActivate('Save As')
}
#create file string from 3 strings: directory,basename returned, file extension
#the return from my output log is: "c:\test_folder\mybasenamestring.PDF"
$mydirectory = "c:\test_folder\"
$mybasename = [io.path]::GetFileNameWithoutExtension($fullname)
$myextension = ".PDF"
$myfilename = "$mydirectory$mybasename$myextension"
#Using tabs to navigate around the dialog window; send my string to the 'File Name' field, then tab to 'Save' and send enter
#This is where the name is actually entered
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{TAB}")
$wshell.SendKeys($myfilename)
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{TAB}")
$wshell.SendKeys("{ENTER}")
#going to add a command to report on the file size of the pdf; the pdf will stay 0kb until its fully generated. Once fully generated will add the $ie.quit or the kill command here for the $ie object
#this sends a stop process command to kill powershell since I'm running it as a ps1 file and it will remain open otherwise
stop-process -Id $PID
最后一件事:我发现大写有些奇怪,因此我更新了最终的SendKeys以大写字符串,因为无论如何我都希望全部大写:
$wshell.SendKeys($myfilename.toupper())
希望这会有所帮助!感谢您的发布;我终于能够完成我的整个过程。在我进行清理和改进时,如果我发现了该方面的改进,我会尽量记住分享。感谢您的帮助!