如何使用 VBScript 中的通用“另存为”对话框?
我想让我的 VBScript 显示 Windows“另存为”对话框,但我不知道如何操作。
使用此代码:
Dim sfd
Set sfd = CreateObject("UserAccounts.CommonDialog")
sfd.ShowOpen
我可以获得一个“打开”对话框,但该对象没有 ShowSave
方法(因为 Visual Basic 非脚本中似乎有类似的对象)。
我搜索了 StackOverflow 并用 google 搜索“[vbscript] 保存对话框”(以及“Windows Script Host”),但我只找到了有关从网页访问常见对话框的线程以及 BrowseForFolder
对话框的解决方案和调用“保存”对话框实际上没什么意义。
实际上,我可以使用“打开”对话框来达到我的目的,因为我需要的只是一个文件名...但由于我想将某些内容保存到所选路径,因此对话框标题栏中的“另存为”将更合适。
I'd like to have my VBScript display the Windows Save As dialog box, but I could not find out how to do it.
Using this code:
Dim sfd
Set sfd = CreateObject("UserAccounts.CommonDialog")
sfd.ShowOpen
I can get an Open dialog, but there is no ShowSave
method for this object (as there seems to be for a similar object in Visual Basic non-script).
I searched StackOverflow and googled for "[vbscript] save dialog" (and with "Windows Script Host"), but I only found threads about accessing common dialogs from web pages and a solution for the BrowseForFolder
dialog and nothing really about calling the Save dialog.
Actually, I can use the Open dialog for my purpose, because all I need is a file name... but as I'd like to save something to the selected path, a "Save As" in the title bar of the dialog would be more appropriate.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
使用 VBScript(或 VBA 或 JScript)中的通用对话框的秘诀是您必须在计算机上安装其许可证。某些开发工具(例如 Visual Basic 6)将安装许可证,但它也由免费的 Microsoft HTML 帮助编辑器(这是一个相当古老的应用程序)安装。有趣的是,如果您安装然后卸载 HTML 帮助编辑器,它会保留通用对话框许可证。因此,我认为该许可证是免费提供的,因此将在我的答案中包含它在此处创建的注册表项:
In
HKLM\Software\CLASSES\Licenses\4D553650-6ABE-11cf-8ADB-00AA00C00905
,将(默认)
条目设置为gfjmrfkfifkmkfffrlmmgmhmnlulkmfmqkqj
。一旦到位,您可以使用如下代码从 VBScript 中创建这些对话框:
要启动文件保存对话框,请使用 ShowSave 方法,如以下代码所示:
当然,该对象还有许多其他方法和属性,并且您可以使用可能需要在启动对话框之前配置适当的属性。例如,您可以设置文件过滤器,以便对话框中仅显示某些文件扩展名。 MSDN 站点上有一个关于该控件的很好的参考:http:// /msdn.microsoft.com/en-us/library/aa259661%28v=vs.60%29.aspx。
希望这有帮助。如果您有任何疑问,请告诉我。
The secret to using the common dialog from VBScript (or VBA or JScript, for that matter) is that you have to have its license installed on your machine. Certain development tools, such as Visual Basic 6, will install the license, but it's also installed by the free Microsoft HTML Help Editor (this is a pretty old app). The interesting thing is that if you install and then uninstall the HTML Help Editor, it leaves the Common Dialog License in place. For this reason I would consider the license to be freely available and so will include the registry entry it creates here in my answer:
In
HKLM\Software\CLASSES\Licenses\4D553650-6ABE-11cf-8ADB-00AA00C00905
, set the(Default)
entry togfjmrfkfifkmkfffrlmmgmhmnlulkmfmqkqj
.Once that's in place, you can create these dialogs from within a VBScript using code like this:
To launch a file save dialog, use the ShowSave method as in this code:
Of course this object has a bunch of other methods and properties, and you'll probably want to configure the appropriate properties before launching the dialog. For example, you can set the file filter so only certain file extensions are shown in the dialog. There's a nice reference to the control on the MSDN site here: http://msdn.microsoft.com/en-us/library/aa259661%28v=vs.60%29.aspx.
Hope this helps. Let me know if you have any questions.
我可以肯定地说,没有解决方案可以在 XP 以外的 Windows 版本下显示 VBScript 的“另存为”对话框,而不依赖于您必须自行安装和注册的某些外部依赖项。 除了显而易见的问题之外这会导致脚本的简单拖放部署受到干扰,还会带来一系列与安全和权限相关的其他问题,特别是绕过客户端计算机上的 UAC 来安装和注册依赖项DLL。
迄今为止提出的解决方案要么依赖于 Windows XP 中恰好包含的 DLL 文件,从 Windows XP 的用户帐户控制面板调用“另存为”对话框,和/或仅为其安装一个软件卸载后留下 MSComDlg DLL,然后可以从 VBScript 中使用它。这些解决方案都没有真正满足上述要求,并且所提供的答案都没有考虑到他们提出的解决方案可能出现的安全障碍,正如我上面提到的。
而且由于您无法从 VBScript 直接调用 Windows API(它非常方便地包含这样一个“另存为”对话框)(不仅因为这会带来安全风险,而且还因为 VBScript 的松散[缺乏?]打字),这几乎让任何想在寒冷中这样做的人都感到惊讶。此外,无法进行 API 调用也阻止了使用任何黑客行为,例如调用 < code>SetWindowText 更改“打开”对话框的标题,如问题中所建议的。
我意识到这不是每个人都想要的答案。这甚至不是我想要的答案。但可惜的是,这是正确的答案。
话虽如此,这里有一些可能的解决方法:
如果您倾向于接受任何已建议的答案,则您已经决定将 DLL 文件的外部依赖项引入到您的 VBScript 部署中。一旦实现了这一飞跃,为什么还要费心“借用”或以其他方式从其他来源劫持 DLL呢?自己做一次就可以了。使用 Visual Basic 6 将 Windows API 提供的本机通用对话框函数包装到 ActiveX DLL 中,然后可以由 VBScript 调用,这很简单。风险很小,因为几乎所有现代版本的 Windows 都已经安装了 Visual Basic 运行时,并且您可能已经了解 VBScript,因此在 VB 6 中编写一些代码应该不是一件非常困难的事情。您可以包含您想要的任何自定义功能,最重要的是,您将完全控制。您不必担心其他应用程序的卸载程序会删除您的脚本所需的 DLL,您不必费力地安装和卸载一些随机的、已弃用的应用程序,并且您不必祈祷。我们知道,作为程序员,这绝不是一个好的选择。
是的,我建议实际包装 Windows API 公开的公共对话框函数,而不是依赖 Visual Basic 提供的公共对话框 OCX (
comdlg32.ocx
)。它在 Windows 7 中也存在一些问题,并且不会为您提供 Windows 更高版本现在提供的华丽的新对话框。 可在 VBnet 上找到。当然,如果您真的想全力以赴,您可以使用常见对话框做很多有趣的事情,所有这些都已记录(带有代码!) VB 加速器上。但是既然我已经说服你们在 VB 6 中编写一个 ActiveX DLL,它封装了要在 VBScript 中使用的通用对话框功能,我必须问一个问题:为什么要停在这里?一旦您开始在 VB 6 中编写一些代码,为什么不将全部代码移至 VB 6 中呢?当然,它是一种“死”语言,但 VBScript 也不是非常活跃。正如我之前提到的,语法上的差异几乎为零,VBScript 开发人员的学习曲线也正如人们所期望的那样浅。另外,您还可以获得完整 IDE 的所有好处、静态类型、(稍微)更好的错误处理等等。哦,是的,并且能够直接调用 Windows API 函数。 VBScript 唯一真正的好处是它的普遍性,但是已经有很多年了,你还找不到一台没有安装 VB 运行时的计算机。更不用说,如果您正在编写需要通用对话框的应用程序,您可能正在与用户进行对话:完整 VB 的表单功能可能会在此时开始派上用场。观点。但也许选择这条路线的最大和最重要的优点是您无需注册(或包含)外部“卫星”DLL - 一个简单的 VB 6 应用程序将仅使用 EXE 在任何具有以下功能的计算机上运行:已安装 VB 运行时,至少在 Windows 7 中包含该功能。
最后,如果您对从低级 VBScript 升级到功能齐全的 VB 6 感到兴奋,我觉得有必要另一个问题是:为什么不直接升级到像 VB.NET 这样的语言呢?再次强调,得益于 .NET Framework,VB.NET 提供了各种新功能,但对于一名优秀的 VB/VBScript 开发人员来说,应该不会超过几周的时间就可以开始轻松地在 VB.NET 中编写应用程序。他们可能不会完全理解 .NET Framework,也肯定不会开发出良好的面向对象设计实践,但至少他们会朝着正确的方向前进。几乎任何可以在 VBScript(甚至 VB 6)中执行的操作,都可以在 VB.NET 中执行。一般来说,由于 .NET Framework 提供了巨大的功能,它比以前需要更少的麻烦。当然,缺点是您的应用程序现在需要在用户计算机上安装 .NET Framework,这并不像 VB 6 运行时那样普遍(尽管它现在比几年前更常见)之前)。
所以我听到您说这些不是您希望听到的解决方法?是的,我也一样。我不是那个告诉人们放弃一切去学习一门新语言的人。如果 VBScript 继续为您工作,继续使用。但如果你已经开始意识到它的局限性,那么可能是时候迈出一步了。
I can definitively say that there is no solution to show a Save As dialog box from VBScript under versions of Windows other than XP without relying on some external dependencies that you must install and register yourself. Aside from the obvious interference this causes with regards to an easy, drag-and-drop deployment of your script, it also brings up a whole host of other issues related to security and permissions, particularly by-passing UAC on the client's machine to install and register a dependency DLL.
The solutions that have been proposed so far rely either on a DLL file that just so happens to be included with Windows XP, invoking the Save As dialog box from Windows XP's User Accounts control panel, and/or installing a piece of software only for it to leave behind the
MSComDlg
DLL after it is uninstalled that you can then use from a VBScript. None of these solutions truly satisfy the above requirements, and none of the provided answers has even considered the possible security roadblocks that would arise with their proposed solutions, as I alluded to above.And since you can't make calls directly to the Windows API (which ever-so-conveniently includes just such a Save As dialog) from VBScript (not only because it would pose a security risk, but also because of VBScript's loose [lack of?] typing), that pretty much leaves anyone wanting to do this out in the cold. As well, the inability to make API calls also precludes the use of any hacks like calling
SetWindowText
to change the caption of the Open dialog, as suggested in the question.I realize that this is not the answer everyone was wanting. It's not even the answer I was wanting. But alas, it's the correct answer.
That being said, here are a couple of possible workarounds:
If you're leaning towards accepting any of the already-suggested answers, you've already decided to introduce an external dependency on a DLL file to your VBScript deployment. Once you've made that leap, why bother with "borrowing" or otherwise hijacking a DLL from some other source? Just make once yourself. It's trivial to wrap the native common dialog functions provided by the Windows API into an ActiveX DLL using Visual Basic 6, which can then be called by your VBScript. The risks are minimal, since almost any modern version of Windows can be expected to already have the Visual Basic run-time installed, and since you presumably already know VBScript, banging out some code in VB 6 shouldn't be a very difficult undertaking. You can include whatever custom functionality that you want, and most importantly, you'll be in complete control. You won't have to worry about other application's uninstallers removing the DLL that your script requires, you won't have to futz with installing and uninstalling some random, deprecated application, and you won't have to just cross your fingers and hope. We know, as programmers, that's never a good option.
And yes, I recommend actually wrapping the common dialog functions exposed by the Windows API, rather than relying on the common dialog OCX (
comdlg32.ocx
) provided by Visual Basic. It has its share of problems in Windows 7, and it's not going to get you the gorgeous new dialogs that the later versions of Windows now provide. An excellent article explaining everything you need to know about the Open and Save Common Dialog APIs and how to use them in VB 6 is available here on VBnet. Of course, if you really want to go all out, there's loads of interesting stuff you can do with common dialogs, all documented (with code!) here on VB Accelerator.But now that I have you all convinced to write an ActiveX DLL in VB 6 that wraps the common dialog functionality to use in your VBScript, I have to ask the question: Why stop there? Once you've made the leap to writing some code in VB 6, why not move all of your code into VB 6? Sure, it's a "dead" language and all, but it's not like VBScript is terribly active either. As I mentioned before, the difference in syntax is virtually nil, and the learning curve for a VBScript developer is about as shallow as one could expect. Plus, you get all of the benefits of a full IDE, static typing, (slightly) better error handling, blah blah blah. Oh yeah, and being able to make direct calls to the Windows API functions. The only real benefit to VBScript is its ubiquity, but it's been years since you could find a computer without the VB runtime installed. Not to mention, if you're writing an application that requires common dialog boxes, you're probably engaging in a dialog with your users: The forms capability of full VB might begin to come in handy at that point. But perhaps the biggest and most important advantage of choosing to go this route is that you eliminate any need to register (or include) an external "satellite" DLL—a simple VB 6 application will run with only the EXE on any computer that has the VB run-time installed, which is included at least up through Windows 7.
And finally, in case you're all sorts of excited about moving up from the lowly VBScript to the full-featured VB 6, I feel compelled to throw another wrench into the equation: Why not move all the way up to a language like VB.NET? Again, there are all sorts of new features offered in VB.NET thanks to the .NET Framework, but it shouldn't take more than a few weeks for a decent VB/VBScript developer to begin to feel comfortable writing apps in VB.NET. They probably won't have a full understanding of the .NET Framework, and they certainly won't have developed good object-oriented design practices, but at least they will be moving in the right direction. Almost anything that you can do in VBScript (or even VB 6), you can do in VB.NET. And generally, it requires even less fuss than before, thanks to the immense functionality exposed by the .NET Framework. The drawback, of course, is that your app now requires the .NET Framework be installed on the user's computer, which isn't quite as ubiquitous as the VB 6 run-time (although it's much more common now than even just a few years ago).
So I hear you saying those weren't the workarounds you were hoping to hear? Yeah, me neither. I'm not that guy who tells people to drop everything and learn a new language. If VBScript continues to work for you, go for it. But if you're at that point where you start to strain at its limitations, it's probably time to make the leap.
如果您对要部署此系统的系统有一定程度的控制,并且可以合理确定它们安装了 Visual Studio 或 Microsoft HTML Help,则可以使用如下代码:
此外,将这个问题的其他答案之一改编为 VBScript 代码(感谢@oddacorn!),如果您不能相当确定您的用户将拥有 VS 或 HTML 帮助,则应该添加此函数。在程序启动时调用该函数。如果您已经拥有钥匙,请不要担心;在这种情况下,这没有任何效果。这应该适用于没有管理员权限的标准用户帐户。
请注意,我从 HTML 此处;在现代 Web 浏览器上,它们用于呈现代码示例的 HTML 似乎无法正确显示(在 IE 8 和 Chrome 上测试)。但幸运的是代码仍然存在于查看源代码中。
我发现一件事对于在 Windows 7(SP1,已完全修补)上运行而言至关重要;您必须设置
dialog.MaxFileSize = 256
,否则您将收到运行时错误。也就是说,以下代码在 Windows 7 SP1 上失败,但可能在旧版本的 Windows 上运行:
If you have some degree of control over the systems on which you'll be deploying this, and can be reasonably certain that they have either Visual Studio or Microsoft HTML Help installed, you can use code like the following:
Also, adapting one of the other answers to this question into VBScript code (thanks @oddacorn!), you should add this function if you aren't reasonably certain that your users will have VS or HTML Help. Call this function on program startup. Don't worry if you already have the key; in that case, this has no effect. This should work on a standard user account without admin rights.
Note that I adapted the filedialog function from the "View Source" of the VBScript code in the HTML here; on modern web browsers, it appears that the HTML they use to render the code samples doesn't display correctly (tested on IE 8 and Chrome). But fortunately the code is still there in the View Source.
I found one thing that was critical to making this work on Windows 7 (SP1, fully patched); you must set
dialog.MaxFileSize = 256
or you will get a run-time error.That is, the following code fails on Windows 7 SP1, but probably works on older versions of Windows:
经过多年的寻找,我在 jsware.net 找到了 jsShell - Shell 组件 。该 zip 文件包含
jsShell.dll
176 kB,一个用于注册 dll 的 vb 脚本regsvr32.exe jsShell.dll
、演示脚本和清晰的文档。该 DLL 在 Windows 7 中运行良好,并提供了多种有用的方法,包括“打开/保存”对话框:
当未选择任何文件时,
sFileName
是一个空字符串。After looking for ages, I've found jsShell - Shell Component at jsware.net. The zip file contains
jsShell.dll
176 kB, a vbscript to register the dll basicallyregsvr32.exe jsShell.dll
, demo scripts and clear documentation.The DLL works well in Windows 7 and provides several useful methods, including the Open/Save dialog:
When no file is selected,
sFileName
is an empty string.在
http://blogs.msdn.com/b/gstemp /archive/2004/02/18/75600.aspx
有一种方法描述了如何从 VBScript 显示“另存为”对话框。
请注意,根据
http://www.eggheadcafe.com /software/aspnet/29155097/safrcfiledlg-has-been-deprecated-by-microsoft.aspx
Microsoft 已弃用 SAFRCFileDlg。
On
http://blogs.msdn.com/b/gstemp/archive/2004/02/18/75600.aspx
there is a way descibed how to show an Save As dialog from VBScript.
Note that according to
http://www.eggheadcafe.com/software/aspnet/29155097/safrcfiledlg-has-been-deprecated-by-microsoft.aspx
SAFRCFileDlg has been deprecated by Microsoft.
我刚刚制作了一个 shell,将其链接到一个 asp 网站,让该网站读取一个定向标记 - 我将文件位置加载到其中,然后 asp 页面会立即在该文件位置中打开文件对话框,文件名也通过定向标签。一旦保存,外壳就会消失。
如果这是网站定向标签的限制,即 (blah.com/temp.aspx?x=0&y=2&z=3)
将信息存储在 SQL 数据库或平面文件中,那么有很多解决方法,但上面所说的是真的。 VBS不会在内部切断它。
I just made a shell, linked it to a asp website, made the website read a directional tag - which i loaded the file location into, and the asp page opens up the file dialog immediate within that file location, with the filename also specificed through directional tags. Once saved, the shell disappears.
If it's a limitation of the website direcitonal tags ie (blah.com/temp.aspx?x=0&y=2&z=3)
store the information in a SQL db, or flat files, there are a ton of workarounds, but what above is said is true. VBS won't cut it internally.
我刚刚在此网站中找到了解决方案
它有完整的注释,并且在 Windows 10 中运行良好
以下是将文件夹作为字符串返回的代码(我在三个不同的启动文件夹中尝试过):
I just found a solution in this site
It is fully commented and works well in Windows 10
Here is the code that returns the folder as a string (I tried in three different start folders):