Подтвердить что ты не робот

Как использовать общий диалог "Сохранить как" в VBScript?

Я бы хотел, чтобы мой VBScript отображал диалоговое окно Windows Save As, но я не мог узнать, как это сделать.

Используя этот код:

Dim sfd
Set sfd = CreateObject("UserAccounts.CommonDialog")
sfd.ShowOpen

Я могу получить диалог Open, но для этого объекта нет метода ShowSave (поскольку, похоже, для аналогичного объекта в Visual Basic не script).

Я искал StackOverflow и googled для "[vbscript] save dialog" (и с "Windows Script Host" ), но я нашел только темы о доступе к общим диалогам с веб-страниц и решение для диалога BrowseForFolder и ничего действительно о вызове диалогового окна "Сохранить".

На самом деле, я могу использовать диалог Open для своей цели, потому что все, что мне нужно, это имя файла... но поскольку я хотел бы сохранить что-то по выбранному пути, в строке заголовка "Сохранить как" диалог будет более уместным.

4b9b3361

Ответ 1

Я могу окончательно сказать, что нет решения, чтобы показать диалоговое окно "Сохранить как" из VBScript под версиями Windows, отличных от XP, не полагаясь на некоторые внешние зависимости, которые вы должны установить и зарегистрировать самостоятельно. из-за очевидных помех это приводит к простому развертыванию вашего script с перетаскиванием и перетаскиванием назад, а также вызывает целый ряд других проблем, связанных с безопасностью и разрешениями, в частности, путем обхода UAC на клиентской машине установить и зарегистрировать зависимую DLL.

Решения, которые были предложены до сих пор, полагаются либо на DLL файл, который так просто входит в Windows XP, вызывая диалоговое окно "Сохранить как" на панели управления учетными записями Windows XP и/или устанавливая часть программного обеспечения только для того, чтобы он оставил библиотеку MSComDlg после ее удаления, которую вы затем можете использовать из VBScript. Ни одно из этих решений действительно не удовлетворяет вышеуказанным требованиям, и ни один из предоставленных ответов даже не рассматривал возможные препятствия безопасности, которые возникли бы с их предлагаемыми решениями, о чем я говорил выше.

И поскольку вы не можете делать вызовы непосредственно в Windows API (который всегда так удобно включает в себя именно такое диалоговое окно "Сохранить как" ) из VBScript (не только потому, что он будет представлять угрозу безопасности, но и из-за VBScript [отсутствие?] ввода текста), что в значительной степени оставляет желающих сделать это на холоде. Кроме того, неспособность совершать вызовы API также исключает использование любых хаков, таких как вызов SetWindowText, чтобы изменить заголовок диалогового окна Open, как предложил в вопросе.

Я понимаю, что это не тот ответ, который все желали. Это даже не тот ответ, который я хотел. Но, увы, это правильный ответ.

Если сказать, вот несколько возможных обходных путей:

  • Если вы склоняетесь к принятию любого из уже предложенных ответов, вы уже решили ввести внешнюю зависимость от DLL файла для развертывания VBScript. После того, как вы совершили этот скачок, зачем беспокоиться о "заимствовании" или иным образом захватывать DLL из какого-то другого источника? Просто сделай один раз сам. Тривиально обернуть собственные общие функции диалога, предоставляемые Windows API, в ActiveX DLL, используя Visual Basic 6, который затем можно вызвать вашим VBScript. Риски минимальны, поскольку почти любая современная версия Windows может ожидать, что уже установлена ​​среда выполнения Visual Basic, и поскольку вы, вероятно, уже знаете VBScript, выбивание кода в VB 6 не должно быть очень сложным делом. Вы можете включить любые настраиваемые функции, которые вы хотите, и, самое главное, вы будете в полном контроле. Вам не придется беспокоиться о том, что другие деинсталляторы приложений, удаляющие DLL, требуемые вашим script, вам не придется futz с установкой и удалением некоторого случайного, устаревшего приложения, и вам не придется просто скрестить пальцы и надеюсь. Мы знаем, как программисты, что никогда не бывает хорошим вариантом.

    И да, я рекомендую фактически обернуть общие функции диалога, открытые API Windows, вместо того, чтобы полагаться на общий диалог OCX (comdlg32.ocx), предоставляемый Visual Basic. Он имеет свою долю проблем в Windows 7, и он не даст вам великолепные новые диалоги, которые предоставляют более поздние версии Windows. Отличная статья, объясняющая все, что вам нужно знать о Open и Save Common Dialog API и о том, как их использовать в VB 6, доступна здесь на VBnet. Конечно, если вы действительно хотите изо всех сил, есть множество интересных вещей, которые вы можете делать с общими диалогами, все документально (с кодом!) здесь, на VB Accelerator.

  • Но теперь, когда я убедил вас написать ActiveX DLL в VB 6, который обертывает общую функциональность диалога для использования в вашем 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? Опять же, есть все новые возможности, предлагаемые в VB.NET благодаря платформе .NET Framework, но для более достойного разработчика VB/VBScript не должно быть больше нескольких недель, чтобы начать чувствовать удобство написания приложений на VB.NET, Вероятно, у них не будет полного понимания .NET Framework, и они, конечно же, не будут разрабатывать хорошие объектно-ориентированные методы проектирования, но, по крайней мере, они будут двигаться в правильном направлении. Почти все, что вы можете сделать в VBScript (или даже VB 6), вы можете делать в VB.NET. И вообще, это требует еще меньше шума, чем раньше, благодаря огромной функциональности, открытой платформой .NET Framework. Недостатком, конечно же, является то, что ваше приложение теперь требует установки .NET Framework на пользовательский компьютер, что не так повсеместно, как и во время работы VB 6 (хотя сейчас это гораздо более распространено, чем даже несколько лет назад).

Итак, я слышу, что вы говорите, что это были не обходные пути, которые вы надеялись услышать? Да, и я. Я не тот парень, который говорит, что люди бросают все и изучают новый язык. Если VBScript продолжает работать на вас, подойдите к нему. Но если вы находитесь в тот момент, когда вы начинаете напрягаться по своим ограничениям, возможно, пора совершить прыжок.

Ответ 2

Секрет использования общего диалога из VBScript (или VBA или JScript, если на то пошло) заключается в том, что вы должны установить свою лицензию на свой компьютер. Некоторые средства разработки, такие как Visual Basic 6, будут устанавливать лицензию, но она также устанавливается в бесплатном редакторе справок Microsoft HTML (это довольно старое приложение). Интересно, что если вы устанавливаете и удаляете редактор справки HTML, он оставляет доступную версию Common Dialog License. По этой причине я считаю, что лицензия будет свободно доступна и поэтому будет включать запись реестра, которую он создает здесь в моем ответе:

В HKLM\Software\CLASSES\Licenses\4D553650-6ABE-11cf-8ADB-00AA00C00905 введите (Default) в gfjmrfkfifkmkfffrlmmgmhmnlulkmfmqkqj.

После этого вы можете создать эти диалоги из VBScript, используя следующий код:

Set objDialog = CreateObject("MSComDlg.CommonDialog")

Чтобы запустить диалог сохранения файла, используйте метод ShowSave, как в этом коде:

objDialog.ShowSave

Конечно, у этого объекта есть множество других методов и свойств, и вы, вероятно, захотите настроить соответствующие свойства перед запуском диалога. Например, вы можете установить фильтр файлов, чтобы в диалоговом окне отображались только определенные расширения файлов. Здесь есть хорошая ссылка на элемент управления на сайте MSDN: http://msdn.microsoft.com/en-us/library/aa259661%28v=vs.60%29.aspx.

Надеюсь, это поможет. Дайте мне знать, если у вас есть вопросы.

Ответ 3

Если у вас есть определенный контроль над системами, на которых вы будете развертывать это, и может быть достаточно уверенным, что у них установлена ​​либо Visual Studio, либо Microsoft HTML Help, вы можете использовать следующий код:

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

Кроме того, адаптируя один из других ответов на этот вопрос в код VBScript (спасибо @oddacorn!), вы должны добавить эту функцию, если не уверены, что ваши пользователи будут иметь VS или HTML Help. Вызовите эту функцию при запуске программы. Не беспокойтесь, если у вас уже есть ключ; в этом случае это не имеет никакого эффекта. Это должно работать на стандартной учетной записи пользователя без прав администратора.

'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

Обратите внимание, что я адаптировал функцию filedialog из "View Source" кода VBScript в HTML здесь; на современных веб-браузерах кажется, что HTML, который они используют для визуализации образцов кода, не отображается правильно (проверен на IE 8 и Chrome). Но, к счастью, код все еще присутствует в View Source.

Я нашел одну вещь, которая была критическая, чтобы эта работа работала в Windows 7 (SP1, полностью исправлена); вы должны установить dialog.MaxFileSize = 256 или вы получите ошибку времени выполнения.

То есть следующий код не работает в Windows 7 с пакетом обновления 1 (SP1), но, вероятно, работает в более старых версиях Windows:

Set x = CreateObject("MSComDlg.CommonDialog")
x.ShowSave

Ответ 5

Я только что создал оболочку, связал ее с веб-сайтом asp, сделал сайт прочитанным направленным тегом, в который я загрузил местоположение файла, и страница asp открывает диалоговое окно файла непосредственно в этом месте файла с именем файла также определяется с помощью направленных меток. После сохранения оболочка исчезает.

Если это ограничение в адресных тегах веб-сайта, то есть (blah.com/temp.aspx?x=0&y=2&z=3)

хранить информацию в SQL файле или плоских файлах, существует тонна обходных решений, но то, что сказано выше, верно. VBS не будет срезать его внутри.

Ответ 6

После поиска веков я нашел jsShell - Компонент оболочки на jsware.net. Zip файл содержит jsShell.dll 176 kB vbscript для регистрации dll в основном regsvr32.exe jsShell.dll демонстрационных скриптов и четкой документации.

DLL хорошо работает в Windows 7 и предоставляет несколько полезных методов, включая диалог Open/Save:

Dim jsS, sFileName
jsS = CreateObject("jsShell.Ops")
' Save as dialog
sFileName = jsS.SaveDlg("<title>", "exe") ' Example: Filter by exe files
sFileName = jsS.SaveDlg("<title>", "")    ' Example: No extension filter
' Open dialog
' Example: Filter by exe, initial dir at C:\
sFileName = jsS.OpenDlg("<title>", "exe", "C:\")

Если файл не выбран, sFileName - пустая строка.

Ответ 7

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

Ответ 8

Set objDialog = CreateObject( "SAFRCFileDlg.FileSave" )

' Note: If no path is specified, the "current" directory will
'       be the one remembered from the last "SAFRCFileDlg.FileOpen"
'       or "SAFRCFileDlg.FileSave" dialog!
objDialog.FileName = "test_save.vbs"
' Note: The FileType property is cosmetic only, it doesn't
'       automatically append the right file extension!
'       So make sure you type the extension yourself!
objDialog.FileType = "VBScript Script"
If objDialog.OpenFileSaveDlg Then
    WScript.Echo "objDialog.FileName = " & objDialog.FileName
End If