Subscribe to this thread
Home - General / All posts - writing result via dialog box

3,101 post(s)
#17-May-18 20:58

I found a neat little chunk of code that allows us to read in a file name (a data path):

Sub Main 

 Set wShell=CreateObject("WScript.Shell")

 Set oExec=wShell.Exec("mshta.exe ""about:<input type=file id=FILE><script>;new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);</script>""")

 sFileSelected = oExec.StdOut.ReadLine

End Sub

from there, we can use that to import a data source.

Now, I want to export some data:

 db.ExportFile "RRInput", GetSystemPath

but, I would like the user to be able to use the dialog boxes to do that. Does anyone have an idea how to modify the above code to allow writing to a new file?

This is really useful for bringing data in and out of 9, so I think it would be a big help to the community.

From the above code, we can select a file, and get the path, but we can't enter the name of a file that isn't already there. I'm guessing it only takes one little change to pull it off.


8,476 post(s)
#18-May-18 08:00

I don’t want to be negative Art, but I’m not convinced that that is a good approach.

Why embed JScript in VBScript, when VBScript alone can do the same? (And why use mshta.exe—which I wasn’t familiar with—another potential “attack surface”?)

For the JScript, why compress it? As your question suggests, that makes it much harder to edit and repurpose.

If you want to use VBScript for this, why not just use VBScript? Everything accessible from JScript is also accessible from VBScript. There are language differences, which might make you pick one over the other, but nothing big.


8,289 post(s)
#18-May-18 08:12

The code has to have multiple layers because the idea is to use the file input control implemented by the browser and it's not easy to reach. Windows used to expose standard dialogs as COM objects, but this stopped quite some time ago and was mostly 32-bit only.


3,101 post(s)
#18-May-18 14:52

you are not being negative, it is a good point. But, this relates to my philosophy about VBScript and Manifold. It is just so quick and dirty, it is almost a crime to not use it. Recall my post about how quickly I can stand up a Form and entire GIS application (BTW, that dog on the couch in the video is the same as my Avatar - she died suddenly about a week ago - a devastating loss for the family).

Any, I digress. I have about 100 different pressure zones that I need to run these simulations on. Manifold 9 makes super quick work of it. VBScript was easy to bang out. Now, I want to give the .map file to an intern and let them just bang out the simulations (read in two files, export out one file).

So, this would not be something that is delivered to client. For that, I'd get a good VB.NET guy to take my VBScript code and just change it around. But, it is super efficient for internal M*A*S*H unit type work where you need to whip something out quickly.


8,289 post(s)
#18-May-18 08:10

This is a pretty roundabout way, indeed, and one of the consequences is that it's really hard to customize the dialog. (The code creates a shell, directs the shell to run an HTML application providing the code in the command line, the HTML application is set up to display a file input control and automatically activate it on launch, then the application tries to pass the resulting value via standard output and the code tries to read it back from the shell. You can see that the file dialog is almost a side effect, it's three layers deep.)

The documentation for the file input offers no way to let the dialog handle new files: file input control.

I suggest just using VB.NET:



' $reference: System.Windows.Forms.dll


Imports System.Windows.Forms


Class Script


Shared Manifold As Manifold.Context

Shared Sub Main()

  Dim dlg As New SaveFileDialog

  dlg.Filter = "CSV Files (*.csv)|*.csv"

  dlg.FilterIndex = 1

  If dlg.ShowDialog() = DialogResult.OK Then



  End If

End Sub


End Class

In the future, we might add commands invoking standard dialogs to the API - or, better yet, make it easier for a script in one language to call a script in a different language and pass results (this can be done now as well, and there are ways to pass results, but these ways are indirect).


3,101 post(s)
#18-May-18 18:02

Thanks, Adam. BTW, I haven't been able to figure out how to instantiate Manifold from outside the application, using VBScript. Using CreateObject with Manifold.Application works with 8, but I don't know how to grab it with 9.


8,289 post(s)
#19-May-18 07:40

You have to use .NET. We no longer register as a COM object. The main reason why is that we don't want system-wide registration, we want to be able to have multiple builds running without conflicts. We might provide a way for COM clients to launch 9 in the future, these will require specific steps from the client application (either put some files to let COM know where the 9 code is without involving the registry, or register a separate DLL manually - one can do the latter now too).

With .NET, you put a copy of EXTNET.DLL into your application and create an instance of Manifold.Root.


3,101 post(s)
#19-May-18 16:32

Does that mean no ability to access the 9 API externally from VBScript, JavaScript, or Python?


8,289 post(s)
#22-May-18 09:18

You can access the API but you cannot use COM to create the starter object, that starter object has to be passed to you. An easy solution is to create a .NET object that instantiates Manifold.Root and exposes a COM interface (this is just an attribute on a class). This way you have your own .NET DLL, you register it as a COM object and then your VBScript code creates an instance of that COM object and asks it to launch 9. We don't have such an object built-in currently, because of the registration, as I explain above.

Manifold User Community Use Agreement Copyright (C) 2007-2017 Manifold Software Limited. All rights reserved.