如何使用VBScript中的“公共另存为”对话框?

如何使用VBScript中的“公共另存为”对话框?,vbscript,savefiledialog,common-dialog,Vbscript,Savefiledialog,Common Dialog,我想让我的VBScript显示“Windows另存为”对话框,但我找不到如何执行该操作 使用此代码: Dim sfd Set sfd = CreateObject("UserAccounts.CommonDialog") sfd.ShowOpen objDialog.ShowSave 我可以得到一个打开的对话框,但是这个对象没有ShowSave方法(就像Visual Basic非脚本中类似的对象一样) 我搜索了StackOverflow并在Google上搜索了“[vbscript]保存对话框

我想让我的VBScript显示“Windows另存为”对话框,但我找不到如何执行该操作

使用此代码:

Dim sfd
Set sfd = CreateObject("UserAccounts.CommonDialog")
sfd.ShowOpen
objDialog.ShowSave
我可以得到一个打开的对话框,但是这个对象没有
ShowSave
方法(就像Visual Basic非脚本中类似的对象一样)

我搜索了StackOverflow并在Google上搜索了“[vbscript]保存对话框”(以及“Windows脚本主机”),但我只找到了有关从网页访问常用对话框的线程和
BrowseForFolder
对话框的解决方案,而没有找到真正有关调用保存对话框的内容

实际上,我可以使用“打开”对话框,因为我只需要一个文件名。。。但由于我想将某些内容保存到所选路径,因此对话框标题栏中的“另存为”更合适。

On 有一种方法描述了如何从VBScript显示另存为对话框

请注意,根据
SAFRCFileDlg已被Microsoft弃用。

使用VBScript(或VBA或JScript)中的公共对话框的秘诀是必须在计算机上安装其许可证。某些开发工具,如Visual Basic 6,将安装许可证,但它也由免费的Microsoft HTML帮助编辑器安装(这是一个非常旧的应用程序)。有趣的是,如果安装并卸载HTML帮助编辑器,它会保留Common Dialog许可证。出于这个原因,我会考虑许可证是免费提供的,因此将包括在这里创建的注册表项在我的答案:

HKLM\Software\CLASSES\Licenses\4D553650-6ABE-11cf-8ADB-00AA00C00905
中,将
(默认)
条目设置为
gfjmrfkfikKffrlmmgmhmnlulkmfmqkqj

设置完毕后,可以使用以下代码从VBScript中创建这些对话框:

Set objDialog = CreateObject("MSComDlg.CommonDialog")
要启动文件保存对话框,请使用以下代码中的ShowSave方法:

Dim sfd
Set sfd = CreateObject("UserAccounts.CommonDialog")
sfd.ShowOpen
objDialog.ShowSave
当然,这个对象还有很多其他的方法和属性,您可能需要在启动对话框之前配置相应的属性。例如,您可以设置文件过滤器,使对话框中仅显示某些文件扩展名。这里有一个很好的MSDN站点控件参考:


希望这有帮助。如果您有任何问题,请告诉我。

我可以肯定地说,在XP以外的Windows版本下,如果不依赖您必须自行安装和注册的某些外部依赖项,则无法从VBScript中显示“另存为”对话框。除了这会对作为脚本的一种简单的拖放部署,它还带来了一系列与安全性和权限相关的其他问题,特别是通过在客户端机器上传递UAC来安装和注册依赖项DLL

迄今为止提出的解决方案要么依赖于恰好包含在Windows XP中的DLL文件,调用Windows XP用户帐户控制面板中的“另存为”对话框,和/或仅安装一个软件,以便在卸载后留下
MSComDlg
DLL,然后可以从VBScript使用该DLL。这些解决方案中没有一个真正满足上述要求,而且所提供的答案中也没有一个考虑到他们提出的解决方案可能会出现的安全障碍,正如我在上面提到的那样

而且,由于无法从VBScript直接调用Windows API(它非常方便地包含这样一个“另存为”对话框)(不仅因为它会带来安全风险,而且还因为VBScript的松散[缺少?]键入),这几乎让任何想这样做的人都束手无策。同样,无法进行API调用也排除了使用诸如调用之类的任何黑客来更改打开对话框的标题,正如问题中所建议的那样

我意识到这不是每个人都想要的答案。这甚至不是我想要的答案。但是,唉,这是正确的答案

话虽如此,这里有几个可能的解决办法:

  • 如果您倾向于接受任何已经建议的答案,那么您已经决定在VBScript部署中引入对DLL文件的外部依赖。一旦你做到了这一点,为什么还要费心“借用”或从其他来源劫持DLL呢?你自己做一次就行了。使用Visual Basic 6将Windows API提供的本机通用对话框函数包装到ActiveX DLL中是很简单的,然后您的VBScript就可以调用该DLL。风险是最小的,因为几乎任何现代版本的Windows都可能已经安装了Visual Basic运行时,而且您可能已经知道VBScript,在VB 6中编写一些代码应该不是一件很困难的事情。您可以包括任何您想要的自定义功能,最重要的是,您将完全控制。您不必担心其他应用程序的卸载程序会删除脚本所需的DLL,也不必费劲安装和卸载一些随机的、不推荐使用的应用程序,也不必祈祷。我们知道,作为程序员,这从来都不是一个好的选择

    是的,我建议实际包装Windows API公开的公共对话框函数,而不是依赖Visual Basic提供的公共对话框OCX(
    comdlg32.OCX
    )。它在Windows7中也有同样的问题,而且它不会为您提供Windows更高版本现在提供的华丽的新对话框。下面是一篇优秀的文章,介绍了有关打开和保存常用对话框API以及如何在VB6中使用它们所需了解的一切。当然,如果你真的想全力以赴,你可以用普通对话框做很多有趣的事情,都有文档记录(用代码!)

  • <
    function filedialog(filt, def, title, save)
        set dialog = CreateObject("MSComDlg.CommonDialog")
        dialog.MaxFileSize = 256
        if filt = "" then
            dialog.Filter = "All Files (*.*)|*.*"
        else
            dialog.Filter = filt
        end if
        dialog.FilterIndex = 1
        dialog.DialogTitle = title
        dialog.InitDir = CreateObject("WScript.Shell").SpecialFolders("MyDocuments")
        dialog.FileName = ""
        if save = true then
            dialog.DefaultExt = def
            dialog.Flags = &H800 + &H4
            discard = dialog.ShowSave()
        else
            dialog.Flags = &H1000 + &H4 + &H800
            discard = dialog.ShowOpen()
        end if
        filedialog = dialog.FileName
    end function
    
    'Make the MSComDlg.CommonDialog class available for use. Required for filedialog function.
    function registerComDlg
        Set objRegistry = GetObject("winmgmts:\\.\root\default:StdRegProv")
        objRegistry.CreateKey &H80000001, "Software\CLASSES\Licenses\4D553650-6ABE-11cf-8ADB-00AA00C00905"
        objRegistry.SetStringValue &H80000001, "Software\CLASSES\Licenses\4D553650-6ABE-11cf-8ADB-00AA00C00905", "", "gfjmrfkfifkmkfffrlmmgmhmnlulkmfmqkqj"
    end function
    
    Set x = CreateObject("MSComDlg.CommonDialog")
    x.ShowSave
    
    Private Sub cmdB1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdB1.Click
        Dim objExec, strMSHTA, wshShell, SelectFile
    
        SelectFile = ""
    
        ' For use in HTAs as well as "plain" VBScript:
        strMSHTA = "mshta.exe ""about:" & "<" & "input type=file id=FILE>" _
                 & "<" & "script>FILE.click();new ActiveXObject('Scripting.FileSystemObject')" _
                 & ".GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);" & "<" & "/script>"""
    
        wshShell = CreateObject("WScript.Shell")
        objExec = wshShell.Exec(strMSHTA)
    
        SelectFile = objExec.StdOut.ReadLine()
        Me.txtT0.Text = SelectFile
        objExec = Nothing
        wshShell = Nothing
        strMSHTA = Nothing
    End Sub
    
    Option Explicit
    
    WScript.Echo BrowseFolder( "C:\Program Files", True )
    WScript.Echo BrowseFolder( "My Computer", False )
    WScript.Echo BrowseFolder( "", False )
    
    
    Function BrowseFolder( myStartLocation, blnSimpleDialog )
    ' This function generates a Browse Folder dialog
    ' and returns the selected folder as a string.
    '
    ' Arguments:
    ' myStartLocation   [string]  start folder for dialog, or "My Computer", or
    '                             empty string to open in "Desktop\My Documents"
    ' blnSimpleDialog   [boolean] if False, an additional text field will be
    '                             displayed where the folder can be selected
    '                             by typing the fully qualified path
    '
    ' Returns:          [string]  the fully qualified path to the selected folder
    '
    ' Based on the Hey Scripting Guys article
    ' "How Can I Show Users a Dialog Box That Only Lets Them Select Folders?"
    ' http://www.microsoft.com/technet/scriptcenter/resources/qanda/jun05/hey0617.mspx
    '
    ' Function written by Rob van der Woude
    ' http://www.robvanderwoude.com
        Const MY_COMPUTER   = &H11&
        Const WINDOW_HANDLE = 0 ' Must ALWAYS be 0
    
        Dim numOptions, objFolder, objFolderItem
        Dim objPath, objShell, strPath, strPrompt
    
        ' Set the options for the dialog window
        strPrompt = "Select a folder:"
        If blnSimpleDialog = True Then
            numOptions = 0      ' Simple dialog
        Else
            numOptions = &H10&  ' Additional text field to type folder path
        End If
    
        ' Create a Windows Shell object
        Set objShell = CreateObject( "Shell.Application" )
    
        ' If specified, convert "My Computer" to a valid
        ' path for the Windows Shell's BrowseFolder method
        If UCase( myStartLocation ) = "MY COMPUTER" Then
            Set objFolder = objShell.Namespace( MY_COMPUTER )
            Set objFolderItem = objFolder.Self
            strPath = objFolderItem.Path
        Else
            strPath = myStartLocation
        End If
    
        Set objFolder = objShell.BrowseForFolder( WINDOW_HANDLE, strPrompt, _
                                                  numOptions, strPath )
    
        ' Quit if no folder was selected
        If objFolder Is Nothing Then
            BrowseFolder = ""
            Exit Function
        End If
    
        ' Retrieve the path of the selected folder
        Set objFolderItem = objFolder.Self
        objPath = objFolderItem.Path
    
        ' Return the path of the selected folder
        BrowseFolder = objPath
    End Function