如何使用powershell设置文件的保存位置?

时间:2017-06-14 11:23:07

标签: powershell printing save

我正在尝试将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]

3 个答案:

答案 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与之交互);这是我将在下面专门讨论的内容,希望能对您有所帮助!

因此,有两点讨论:

  1. 首先,更多的是常规观察/查询:我看不到$ xps_dir变量的实际定义位置;我之所以这样说是因为$ xps_dir传递的值可能与字符串有关。检查字符串以确保其“漂亮”的一种方法是使用OUT-FILE命令将其传递到.txt或其他内容:

“ $ xps_dir” |外文件-FilePath“ C:\ somefolder \ sometext.txt”-追加

文本文件本身不需要存在,但文件确实存在...上面的命令将创建文本文件。

此外,如果您可以查看Powershell提示,可以使用WRITE-HOST。

无论哪种方式,我都想知道最终的编译字符串是否编译不正确,因此无法将其识别为目录。

  1. 我认为更可能发生的是未将SENDKEYS发送到正确的字段。例如,通过使用您的代码,我[终于可以]将“另存为”对话框设置为对象并与其进行交互。 (使用PDF打印机时,出现“另存为”对话框)。

首先,我尝试发送文件名,然后发送回车。我认为这很好,因为在手动交互过程中,“另存为”对话框的焦点移到了“文件名”字段。但是,尝试之后:

$ 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的缺点:

  1. 已作为活动进程运行;用户无法使用其他任何窗口,否则可能会将密钥发送给他们;
  2. 键是基于计数的;该计数的任何变化都将需要更新/编辑子例程,从而使其不具有弹性;

此外,我还没有完成有关错误窗口的任何工作,但是我已经注意到的一个问题是“您的文档名称相同等等”,所以请注意。

即使我们正在做两种不同的事情,这还是例程的这一部分的最终代码,以防它有助于提供上下文:

#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())

希望这会有所帮助!感谢您的发布;我终于能够完成我的整个过程。在我进行清理和改进时,如果我发现了该方面的改进,我会尽量记住分享。感谢您的帮助!