2

I am currently running a new vbscript from my main vbscript by creating the 2nd script 'on the fly' from array of strings and writing it to external secondfile.vbs file, then using WshShell.Run "C:\secondfile.vbs" I need it to keep running while the 1st one is running as well.

The problem I have is, since I have to repeat it many times, writing the new vbs file using FSO slows the process down a bit - I am trying to eliminate that. Is there a way to run a vbscript from the memory, without creating a physical file? Looking for a way to get my script as strings and execute directly as independent vbscript. Thanks in advance for any suggestions.

Here is a simplified code of how it currently works:

Option Explicit

'this is the main RhinoScript file
Call MainRhinoScript()
Sub MainRhinoScript()

    'create Wscript.Shell object
    Dim WshShell : Set WshShell = CreateObject("WScript.Shell")
    Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject"): 
    'get or create user settings plugin folder and vbs file path string 
    Dim strVBSEventWatcherFile : strVBSEventWatcherFile = "C:\eventwatcher.vbs"

    Do
        'create auto-generated vbs file here and run it
        Call WriteVBS_EventWatcher_File(strVBSEventWatcherFile,
        Call WshShell.Run(strVBSEventWatcherFile)

        'The main code goes here, looped until done.
        'VBS eventwatcher script file is running simultaneously.
    Loop

End Sub

'this is simplified VBS writing subroutine to demonstrate how the code works, the actual one is much longer:
Private Sub WriteVBS_EventWatcher_File(strFilePath)

    Dim i,fso : Set fso = CreateObject("Scripting.FileSystemObject")
    Dim file : Set file = fso.CreateTextFile(strFilePath, True)

    file.WriteLine("Option Explicit")
    file.WriteLine("")
    file.WriteLine("Call Main()")
    file.WriteLine("Sub Main()")
    file.WriteLine("    Dim WshShell : Set WshShell = CreateObject(""WScript.Shell"")'create shell script object")
    file.WriteLine("WScript.Sleep 10")
    file.WriteLine("WshShell.SendKeys ""Rhino_Preselect "" ")
    file.WriteLine("End Sub")   
    file.Close()

End Sub
omegastripes
  • 12,351
  • 4
  • 45
  • 96
Jarek
  • 29
  • 4
  • Looks like an [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) to me. Please describe the actual problem you're trying to solve. – MikeC Apr 22 '16 at 18:51
  • Hi @MikeC, you can ignore the first part if you don't need to know the context. The simple question is: "is there a way to create a vbscript in memory and run it without creating a vbs file on HD?" – Jarek Apr 22 '16 at 19:21
  • The situation is the exact opposite. Read the link to the "XY Problem." I'm asking to know more about what you're actually trying to achieve. – MikeC Apr 22 '16 at 20:19
  • @MikeC - as you can tell I am relatively new here and not very advanced scripter/programmer either. Just using my best judgement to formulate the thing I am after without getting into neccessary details. But to give you better idea: In fact my main script is a RhinoScript - a vbscript-based language for automating Rhinoceros3D software. It comes with some limitations that I am trying to work around. So - sometimes I am creating an external 'event watcher' vbscript from Rhino that reacts to key presses and mouse clicks and talks back with RhinoScript via Windows Registry. Thx for reading. – Jarek Apr 22 '16 at 20:45

1 Answers1

2

The simplest way to run some code withing running WSH VB script is to pass the code to ExecuteGlobal function (or Execute using local scope):

arrCode = Array(_
    "For x = 1 To 10", _
    "MsgBox x", _
    "Next"_
    )

strCode = Join(arrCode, vbCrLf)

ExecuteGlobal strCode

You can find VBScript "multiprocess" implementation by the link. The code works only for WSH scripting engine. RhinoScript environment need that code to be reworked and adapted, since there are the differences: RhinoScript has no WScript object available, so the issue is that the path to launched RhinoScript file couldn't be retrieved. The only way is to hardcode the path in the code. Also WSH VBS file extension is .vbs, and for RhinoScript it is .rvb.

Some stuff has become clearer from the comments. You wrote that you are trying to gain more speed running the code on the fly, but note that WshShell.SendKeys method takes much longer time than saving and executing the file, and it's unreliable. My clue is to avoid using .SendKeys and try to implement automation using RhinoScript object model application methods. Perhaps going that way you won't need any code creation. It depends on what you initially intended to automate.

Also you pointed that the vbscript code snippets are created, modified and executed many times from one main RhinoScript runtime, one by one. So, even continuing with your initial script it's not quite clear why is it necessary to make any "multiprocess" model? Why not to create each snippet and to pass it to ExecuteGlobal as in my example above?

omegastripes
  • 12,351
  • 4
  • 45
  • 96
  • Thank you very much for the answer - I think I need the 'another trick', to run the created code simultaneously... – Jarek Apr 22 '16 at 20:43
  • @Jarek There is "multiprocess" VBScript implementation but it only works for WSH (should be launched `.vbs` file saved on a drive, and has `WScript` object accessible). As I can see now from your comment you are using RhinoScript that is actually a flavour of WSH VBS, and I'm guessing there is neither the script file saved on a drive nor `WScript` object. – omegastripes Apr 22 '16 at 21:23
  • I see; now there is actually a vbscript file on the drive that is being created on the fly by RhinoScript and all works well and multithreaded. What I was trying to see is if I can do the same thing without saving the file, just run it from memory somehow to gain more speed. Thank you very much for looking into this. – Jarek Apr 22 '16 at 22:02
  • @Jarek for the mentioned "multiprocess" approach it should be at least one `.vbs` file saved on the drive. Otherwise the generated code and source script will be running sequentially, not simultaneously. – omegastripes Apr 22 '16 at 22:05
  • so the main RhinoScript is saved on the drive (that's the one that generates the vbs code). Now I am also saving the vbs and running it via 'WshShell.Run'. Just confirming that that's the best I can do. Would you have a sample code for the multiprocess method you mentioned available ? – Jarek Apr 22 '16 at 22:27
  • Do you have `WScript` object available in your environment? Try to add the line e. g. `MsgBox WScript.ScriptFullName`. – omegastripes Apr 22 '16 at 22:45
  • I can get the WScript object via: `Dim objShell : Set objShell = CreateObject("WScript.Shell")` `objShell.ScriptFullName()` does not work though in RhinoScript; other methods do (like .Run, .UserName, etc.) – Jarek Apr 22 '16 at 23:09
  • This won't work, [WScript.Shell](https://msdn.microsoft.com/en-us/library/aew9yb99.aspx) doesn't have `.ScriptFullName` property. – omegastripes Apr 22 '16 at 23:14
  • Are you intend to create and execute the code on the fly many times per one RhinoScript call? Also the question is how to retrieve within RhinoScript the full path to itself. – omegastripes Apr 22 '16 at 23:19
  • Yes, the vbscript code is created, modified and executed many times from one main RhinoScript runtime, – Jarek Apr 22 '16 at 23:23
  • 1
    Are created vbscript snippets executed one by one or simultaneously also? Better you to add the full code to your question to make it more clear. – omegastripes Apr 22 '16 at 23:27
  • They are always created one by one. I have added simplified code to the main question. – Jarek Apr 22 '16 at 23:54
  • @Jarek I've updated my answer. Have you done what you intended? – omegastripes May 06 '16 at 17:11