topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Friday December 6, 2024, 11:40 pm
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: How to -connect- Windows Visual Basic Apps with Windows Batch files?  (Read 8037 times)

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
For example, here is what is done between two batch files:
In demo.bat,
set tmp=ABC
...
call main.bat
---

In main.bat,
if not "%tmp%"="" echo got it, %%tmp%% = %tmp% ... it worked!!
---

Now without a 'demo.bat' file, how can I pass my %tmp% variable from Windows 7 to my main.bat?

Phil
PS tried following
' Create a script (within my VB app) to pass parameters to Windows Batch file
' nogo as of 7/13/2018 pbb, need help!

' oShell.run "cmd /V /C Set -ua tmp %" & "ABC", 3, True

f0dder

  • Charter Honorary Member
  • Joined in 2005
  • ***
  • Posts: 9,153
  • [Well, THAT escalated quickly!]
    • View Profile
    • f0dder's place
    • Read more about this member.
    • Donate to Member
Instead of using environment variables, can't you use commandline arguments instead?
- carpe noctem

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,644
    • View Profile
    • Donate to Member
As f0dder said, just pass the variable to the command file.

Code: Text [Select]
  1. Process.Start("main.bat", "ABC")

The passed argument is referred to as %1 in the command file, eg.

main.bat
Code: Text [Select]
  1. @echo off
  2. if "%~1"  == "ABC" (echo We got something!) else echo We got nothing!

%~1 removes any leading/trailing quotes, (eg. "ABC" becomes ABC), in case the arg did include spaces, and then you include it in quotes to do the string comparison.

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
Not that simple ... many parameters are passed as is.  So, how to get a variable passed that bypasses the cmd line?  And, there are many ... many apps already developed that need this technique.

Thanks, Phil

f0dder

  • Charter Honorary Member
  • Joined in 2005
  • ***
  • Posts: 9,153
  • [Well, THAT escalated quickly!]
    • View Profile
    • f0dder's place
    • Read more about this member.
    • Donate to Member
Since your post mentions "oShell.run", I guess you're dealing with VBScript and not VB code?

In general, a parent process passes its environment down to a child process. At the operating system level, you can usually specify a new environment for the child process (e.g. to pass it data, like you want to). It doesn't seem like this is available in VBScript, though, so you're probably limited to the way you're currently trying to do it, prepending /set before the command you want to run.

A thing that springs to mind is you do "set -ua" - I don't know what the "u" parameter is supposed to do (not listed on my system with "set /?"), but more generally Windows uses forward-slash for arguments, not dash.

Here's a little cmd.exe session, which I hope will be instructive:
shot-2018-07-17@18.35.17.pngHow to -connect- Windows Visual Basic Apps with Windows Batch files?

Also note that child environment is never propagated back to the parent process.
- carpe noctem

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
I got this "set -ua ..." off the www as a possible answer to my question.  I write VB code and VBscript when necessary.

Anyone out there knows how to pass an environment variable from Windows?

Phil

f0dder

  • Charter Honorary Member
  • Joined in 2005
  • ***
  • Posts: 9,153
  • [Well, THAT escalated quickly!]
    • View Profile
    • f0dder's place
    • Read more about this member.
    • Donate to Member
I got this "set -ua ..." off the www as a possible answer to my question.
-OptimalDesigns (July 17, 2018, 03:28 PM)
Where? Considering "u" isn't a valid argument to set, and "-" being the wrong argument specifier, that just seems like bad advice.

I write VB code and VBscript when necessary.
-OptimalDesigns (July 17, 2018, 03:28 PM)
VBScript (probably) requires the hack from your original post, VB should be able to use normal environment passing. Which language do you need the solution for? And if it's VB, is it old-school VB or VB.NET? And which version?

Anyone out there knows how to pass an environment variable from Windows?
-OptimalDesigns (July 17, 2018, 03:28 PM)
It's the seventh argument to CreateProcess ;)
- carpe noctem

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
Visual Basic with .Net support (code from Microsoft)
Module Example
   Public Sub Main()
      Dim envName As String = "AppDomain"
      Dim envValue As String = "True"

      ' Determine whether the environment variable exists.
      If Environment.GetEnvironmentVariable(envName) Is Nothing Then
         ' If it doesn't exist, create it.
         Environment.SetEnvironmentVariable(envName, envValue)
      End If

      Dim createAppDomain As Boolean
      Dim msg As Message
      If Boolean.TryParse(Environment.GetEnvironmentVariable(envName),
                          createAppDomain) AndAlso createAppDomain Then
         Dim domain As AppDomain = AppDomain.CreateDomain("Domain2")
         msg = CType(domain.CreateInstanceAndUnwrap(GetType(Example).Assembly.FullName,
                                                    "Message"), Message)
         msg.Display()                                                                           
      Else
         msg = New Message()
         msg.Display()   
      End If     
   End Sub
End Module

Public Class Message : Inherits MarshalByRefObject
   Public Sub Display()
      Console.WriteLine("Executing in domain {0}",
                        AppDomain.CurrentDomain.FriendlyName)
   End Sub
End Class


Visual Basic Script example
Set wshShell = CreateObject( "WScript.Shell" )
Set wshSystemEnv = wshShell.Environment( "SYSTEM" )
' Display the current value
WScript.Echo "TestSystem=" & wshSystemEnv( "TestSystem" )

' Set the environment variable
wshSystemEnv( "TestSystem" ) = "Test System"

' Display the result
WScript.Echo "TestSystem=" & wshSystemEnv( "TestSystem" )
' Delete the environment variable
wshSystemEnv.Remove( "TestSystem" )
' Display the result once more
WScript.Echo "TestSystem=" & wshSystemEnv( "TestSystem" )
Set wshSystemEnv = Nothing
Set wshShell     = Nothing

Does that answer your question?

My question would be, why using batch files while having developing software (in your case VB/VBS) ?
« Last Edit: July 17, 2018, 07:48 PM by KodeZwerg »

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,644
    • View Profile
    • Donate to Member
I got this "set -ua ..." off the www as a possible answer to my question.
-OptimalDesigns (July 17, 2018, 03:28 PM)

set -u is used in Linux Bash shells.
set /a is used in Windows CLI to set environment variables using arithmetic expressions. eg. set /a "ABC+=2"

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
Set wshShell = CreateObject( "WScript.Shell" )
Set wshSystemEnv = wshShell.Environment( "SYSTEM" )
' Display the current value
WScript.Echo "TestSystem=" & wshSystemEnv( "TestSystem" )
Close ... I have the following code that may explain my problem.
        Dim oShell As Variant, intResponse As Integer
        Set oShell = CreateObject("WSCript.shell")
---
Your example shows "Set wshShell = " and mine has "Set oShell = ".  So, I made that change but then "Set wshSystemEnv = " produces an error msg. saying that "wshSystemEnv" is not defined.  So, "Dim wshSystemEnv As Variant" line was added but that caused other problems. 

Next, the line 'WScript.Echo "TestSystem=" & wshSystemEnv("TestSystem")
' causes an error abort msg.  It seems that it doesn't like the "WScript.Echo" portion, but not sure what it is trying to point too.  Ideas?

Thanks for the help!  Close ... so close!
Phil

f0dder

  • Charter Honorary Member
  • Joined in 2005
  • ***
  • Posts: 9,153
  • [Well, THAT escalated quickly!]
    • View Profile
    • f0dder's place
    • Read more about this member.
    • Donate to Member
Set wshSystemEnv = wshShell.Environment( "SYSTEM" )
Do. Not. Do. This.

You'll be setting a system-wide environment variable - this is a bad, bad, bad idea unless you're specifically aiming to do that. Fortunately, at least on modern Windows versions, vbscript isn't allowed to do this, unless you're running it with admin privileges.

If you need to use vbscript instead of a proper language, go for the solution that executes cmd /c "set foo=bar & mainexecutable".
- carpe noctem

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
Sorry my fault.

f0dder

  • Charter Honorary Member
  • Joined in 2005
  • ***
  • Posts: 9,153
  • [Well, THAT escalated quickly!]
    • View Profile
    • f0dder's place
    • Read more about this member.
    • Donate to Member
Could you enlighten me why it is bad to set/unset global environment? That it is bad you mentioned, the "because" is missing. Thanks in advance!
Sure thing :)

First, notice that the global environment is persistent. You shouldn't be making persistent changes to the user's system unless that is what the user directly expects. If there's a name clash, you're going to overwrite the user's own setting, and if your program crashes, you leave a garbage environment variable behind.

By using global environment, you get re-entrancy issues - if you launch multiple child processes simultaneously, you risk several children getting the parameters for one of them.

And then there's the issue of admin privileges necessary for setting system environment variables, which makes this unsuitable for a general mechanism.

Finally, you should generally strive to adhere to the principle of least surprise, and keep mutable state as local as possible - since that leads to fewer bugs, and has the bugs that slip past you be easier-to-debug ones.
- carpe noctem

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
Wow, you are FAAAAAAAAAAAAAAST. Even faster than my "Save" -> "Modify Message" -> "Save"
At first clicking "Save" most of your statements rushed through my brain so i've removed my Message.

Big thanks for explaining!

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
Set wshSystemEnv = wshShell.Environment( "SYSTEM" )
Do. Not. Do. This.

If you need to use vbscript instead of a proper language, go for the solution that executes cmd /c "set foo=bar & mainexecutable".

I'm a little lost here ... so we are back to cmd /c "set foo=bar & mainexecutable"?  What is the '"mainexecutable"?  This -must- be "set" before executing my main batch file.  So, will or should my oShell.run "cmd /C Set tmp = "ABC" do the trick?

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
it worked!!!   oShell.run "cmd /C set win~dir=" & fileTempPath & " && " & tmp3, 3, True
"win~dir" is my environment variable that passed windows present path, fileTempPath, to the 'bat' file.

My problem was due to a shortcut to my FC-base.bat file, called FC-base-launch.lnk.  If the 'bat' file was called directly from my windows app, all was fine.  But, call a shortcut 'launch' link and the users path was lost. :(  These 'launch' links allow users to define their text & background colors, text fonts & sizes, etc. ... very helpful for developers to let the owners decide these things.  A bat file does -not- have such options.

Thanks KodeZwerg & f0dder for your help!
Phil