2

我只是想批量打印文件夹中的大量文件。该文件夹包含多种文件类型,我只想调用等效于Right-Click > Print.

看来我应该能够使用对象的InvokeVerb方法来做到这一点Shell32.FolderItem。所以,我不知道为什么,当我运行下面的代码时,什么也没有打印出来。

有任何想法吗?

GetFolder只是Shell32.BrowseForFolder返回所选文件夹路径的函数的包装器。该函数可以正常工作。对于测试,您只需替换为文件夹的路径即可。)

Sub printFOO()
    Dim shApp           As Shell32.Shell
    Dim srFSO           As Scripting.FileSystemObject
    Dim strPath         As String
    Dim shFIcol         As Shell32.FolderItems
    Dim shFIx           As Shell32.FolderItem
    Dim shFLDx          As Shell32.Folder
    Dim lngX            As Long

    Set shApp = New Shell32.Shell
    Set srFSO = New Scripting.FileSystemObject

    strPath = GetFolder("Choose a folder...")

    Set shFLDx = shApp.NameSpace(strPath)
    Set shFIcol = shFLDx.Items()


    For Each shFIx In shFIcol
            'For lngX = 0 To shFIx.Verbs.Count
                'Debug.Print shFIx.Verbs.ITEM(lngX).Name
            'Next
            'msgbox("printing "&shFIx.name)
            shFIx.InvokeVerb ("&Print")
            DoEvents
    Next
End Sub
4

4 回答 4

2

这是一个使用稍微不同的方法执行此操作的程序。它还列出了可用的动词。

HelpMsg = vbcrlf & "  ShVerb" & vbcrlf & vbcrlf & "  David Candy 2014" & vbcrlf & vbcrlf & "  Lists or runs an explorer verb (right click menu) on a file or folder" & vbcrlf  & vbcrlf & "    ShVerb <filename> [verb]" & vbcrlf & vbcrlf & "  Used without a verb it lists the verbs available for the file or folder" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & "  The program lists most verbs but only ones above the first separator" & vbcrlf & "  of the menu work when used this way" & vbcrlf & vbcrlf 
HelpMsg = HelpMsg & "  The Properties verb can be used. However the program has to keep running" & vbcrlf & "  to hold the properties dialog open. It keeps running by displaying" & vbcrlf & "  a message box." 
Set objShell = CreateObject("Shell.Application")
Set Ag = WScript.Arguments 
set WshShell = WScript.CreateObject("WScript.Shell") 
Set fso = CreateObject("Scripting.FileSystemObject")

    If Ag.count = 0 then 
        wscript.echo "  ShVerb - No file specified"
        wscript.echo HelpMsg 
        wscript.quit
    Else If Ag.count = 1 then 
        If LCase(Replace(Ag(0),"-", "/")) = "/h" or Replace(Ag(0),"-", "/") = "/?" then 
            wscript.echo HelpMsg 
            wscript.quit
        End If
    ElseIf Ag.count > 2 then 
        wscript.echo vbcrlf & "  ShVerb - To many parameters" & vbcrlf & "  Use quotes around filenames and verbs containing spaces"  & vbcrlf
        wscript.echo HelpMsg 
        wscript.quit
    End If

    If fso.DriveExists(Ag(0)) = True then
        Set objFolder = objShell.Namespace(fso.GetFileName(Ag(0)))
'       Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
        Set objFolderItem = objFolder.self
        msgbox ag(0)
    ElseIf fso.FolderExists(Ag(0)) = True then
        Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
        Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
    ElseIf fso.fileExists(Ag(0)) = True then
        Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
        Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
    Else
        wscript.echo "  ShVerb - " & Ag(0) & " not found"
        wscript.echo HelpMsg 
        wscript.quit
    End If

    Set objVerbs = objFolderItem.Verbs

    'If only one argument list verbs for that item

    If Ag.count = 1 then
        For Each cmd in objFolderItem.Verbs
            If len(cmd) <> 0 then CmdList = CmdList & vbcrlf & replace(cmd.name, "&", "") 
        Next
        wscript.echo mid(CmdList, 2)

    'If two arguments do verbs for that item

    ElseIf Ag.count = 2 then
        For Each cmd in objFolderItem.Verbs
            If lcase(replace(cmd, "&", "")) = LCase(Ag(1)) then 
                wscript.echo Cmd.doit 
                Exit For
            End If
        Next
    'Properties is special cased. Script has to stay running for Properties dialog to show.
        If Lcase(Ag(1)) = "properties" then
            WSHShell.AppActivate(ObjFolderItem.Name & " Properties")
            msgbox "This message box has to stay open to keep the " & ObjFolderItem.Name & " Properties dialog open."
        End If  
    End If
End If
于 2014-11-21T17:29:11.877 回答
1

您不需要 FSO 进行文件夹浏览对话。尝试shApp.BrowseForFolder(0, "Select Folder to print from", 0, 0)。通过这种方法,您可以直接获得 shell 文件夹对象。此外,如果是文件或文件夹,您可能需要检查每个文件夹项。

Sub printFgOO()
    Dim shApp           As Shell32.Shell
    Dim shFIcol         As Shell32.FolderItems
    Dim shFIx           As Shell32.FolderItem
    Dim shFLDx          As Shell32.Folder
    Dim lngX            As Long

    Set shApp = New Shell32.Shell
    Set shFLDx = shApp.BrowseForFolder(0, "Select Folder to print from", 0, 0)
    Set shFIcol = shFLDx.Items()

    For Each shFIx In shFIcol
        If Not shFIx.IsFolder Then    ' Print only if is file
            shFIx.InvokeVerb ("&Print")
            DoEvents
        End If
    Next
End Sub

或者尝试这里描述的函数 ShellExecute !

于 2014-11-21T13:51:03.070 回答
0

好的,所以对于为什么InvokeVerb方法无法打印,我仍然没有答案,但是我现在确实有一种方法可以使用ShellExecute@Radek 建议的功能来打印文件。

想我会在这里分享我的工作代码。随时提出改进建议;)

Option Explicit

Public Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteW" (ByVal hWnd As Long, _
                                                                    ByVal lpOperation As LongPtr, _
                                                                    ByVal lpFile As LongPtr, _
                                                                    ByVal lpParameters As LongPtr, _
                                                                    ByVal lpDirectory As LongPtr, _
                                                                    ByVal nShowCmd As Long) As Long


Public Const SW_HIDE As Long = 0
'Hides the window and activates another window.

Public Const SW_MAXIMIZE  As Long = 3
'Maximizes the specified window.

Public Const SW_MINIMIZE  As Long = 6
'Minimizes the specified window and activates the next top-level window in the z-order.

Public Const SW_RESTORE  As Long = 9
'Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when restoring a minimized window.

Public Const SW_SHOW  As Long = 5
'Activates the window and displays it in its current size and position.

Public Const SW_SHOWDEFAULT  As Long = 10
'Sets the show state based on the SW_ flag specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application. An application should call ShowWindow with this flag to set the initial show state of its main window.

Public Const SW_SHOWMAXIMIZED  As Long = 3
'Activates the window and displays it as a maximized window.

Public Const SW_SHOWMINIMIZED  As Long = 2
'Activates the window and displays it as a minimized window.

Public Const SW_SHOWMINNOACTIVE  As Long = 7
'Displays the window as a minimized window. The active window remains active.

Public Const SW_SHOWNA  As Long = 8
'Displays the window in its current state. The active window remains active.

Public Const SW_SHOWNOACTIVATE  As Long = 4
'Displays a window in its most recent size and position. The active window remains active.

Public Const SW_SHOWNORMAL  As Long = 1
'Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when displaying the window for the first time.

Public Enum shexActions
    shexEDIT
    shexEXPLORE
    shexFIND
    shexOPEN
    shexPRINT
End Enum

Private Function getShellAction(ByRef enACTION As shexActions) As String
    Select Case enACTION
        Case shexActions.shexEDIT
            getShellAction = "EDIT"
        Case shexActions.shexEXPLORE
            getShellAction = "EXPLORE"
        Case shexActions.shexFIND
            getShellAction = "FIND"
        Case shexActions.shexOPEN
            getShellAction = "OPEN"
        Case shexActions.shexprint
            getShellAction = "PRINT"
    End Select
End Function



Public Function ShellEx(ByRef strFILE As String, _
                        Optional ByRef lngWINDOWHANDLE As Long = 0, _
                        Optional ByRef shexACTION As shexActions = (-1), _
                        Optional ByRef strPARAMETERS As String, _
                        Optional ByRef strDIRECTORY As String, _
                        Optional ByRef lngSHOWCOMMAND As Long = 0) As Long

    Dim lngReturnCheck As Long

    lngReturnCheck = (-1)

    lngReturnCheck = ShellExecute(hWnd:=lngWINDOWHANDLE, lpOperation:=StrPtr(getShellAction(shexACTION)), lpFile:=StrPtr(strFILE), lpParameters:=StrPtr(strPARAMETERS), lpDirectory:=StrPtr(strDIRECTORY), nShowCmd:=lngSHOWCOMMAND)

        While lngReturnCheck = (-1)
            DoEvents
        Wend

    ShellEx = lngReturnCheck
End Function

Sub printBAR()
    Dim shFIcol         As Shell32.FolderItems
    Dim shFIx           As Shell32.FolderItem
    Dim shFLDx          As Shell32.Folder
    Dim lngX            As Long

    Set shFLDx = GetFolder("Choose a folder...", True)

    Set shFIcol = shFLDx.Items()

    For Each shFIx In shFIcol
            lngX = ShellEx(shFIx.Path, , shexPRINT)
            Debug.Print lngX
    Next
End Sub
于 2014-11-21T16:45:24.173 回答
0

如果您愿意使用 powershell 来解决这个问题:

#Save this as Print-Files.ps1
[CmdletBinding()]
param(
    [Property(Mandatory=$true,
        ValueFromPipelineByPropertyName=$true,
        Position=0)]
    [string]$Path)


foreach($file in (Get-ChildItem $path ))
{
    Start-Process –FilePath $file.FullName –Verb Print
}
于 2014-11-23T15:34:43.023 回答