1

I have the following sub:

Public Sub ShellApp(URL As String)

        Dim vResult As Long
        vResult = ShellExecute(0, "open", URL, vbNullString, vbNullString, vbMinimizedFocus)

   End If
End Sub

This is on a layer that cannot be changed due to several functionality needed on that sub.

Now, on our Main() sub for example, we check a list of added plugins saved in a text file beside the EXE, and call the above Sub in for loop with the path of the plugins to run them. So if I have 3 plugins as below in the text file:

C:\App1.EXE

C:\App2.EXE

C:\Users\AhmadMusa\AppData\Roaming\App3.exe

First two apps will run fine on all PCs (Static path), but third app will not work on any PC except mine which is not ok... Note that App3 always installed on AppData on any PC, so how to dynamically access it to run the app from any PC without adjustments on the sub.

What will be the path placed in the text file for third app so it can work on all PCs?

I tried (AppData\Roaming\App3.exe) but it does not work... I found on a thread (http://www.vbforums.com/showthread.php?529776-RESOLVED-Open-a-folder-in-AppData) that I can call something like (shell:AppData\Roaming\App3.exe) it did not work to run the App3.exe, but if I call (shell:AppData\Roaming) it will open the Roaming folder very well. But cannot run the EXE.

Any ideas ?

Thanks.

Ahmad Mousa
  • 745
  • 2
  • 7
  • 18
  • Well, still it seems am not making my self clear. I know how to get AppData path using code, am not running apps through app data all the time. I have a function that take argument the path I want to run, and then I shell execute this path taken from argument. This argument is custom which means it can be changed to anything you can imagine (user defined) can be c:\app.exe can be d:\app.exe or anything else..Now, what shall I send to this argument to run app placed in AppData "at runtime" I shall send this argument at run time (from our buffers file where we save the app path) on our first run – Ahmad Mousa Jun 09 '17 at 13:06
  • If I understand you, the user can move your application to anyplace on their system and you want to maintain the ability to start the application through your interface. If that is correct, unless they move your application to someplace on the system path you will need a way to store the path of the new location. – jac Jun 09 '17 at 19:34
  • @jac I have an application installed anyplace which contains the ability to run any third party application from within, so we have a tab where we place all third parties plugins. Such plugins sometimes on c drive, d drive or any where. Now assume I have an application installed on app data folder, how can I call it from our application? What shall I put on the path? A Google search guided to put the path as ("shell:AppData\some folder\") and this worked to open the explorer on that place, but not running the exe. – Ahmad Mousa Jun 09 '17 at 19:52

3 Answers3

0

You need to expand the Environment variable (this is what the %...% does):

Debug.Print Environ("APPDATA") ' will print the expanded %appdata%

So, in your text file you should put:

%APPDATA%\App3.exe

How to expand the path? You can loop over the environment variables provided by the VB Environ function and do a string replace by yourself (the VB way) or you can profit from the ExpandEnvironmentStrings function (the Win32 API way).

Below a snippet using this second option:

Private Declare Function ExpandEnvironmentStrings Lib "kernel32.dll" _
                Alias "ExpandEnvironmentStringsA" ( _
                ByVal lpSrc As String, _
                ByVal lpDst As String, _
                ByVal nSize As Long) As Long

Public Function ExpandEnvironString(ByVal URL As String) As String
    Dim buf As String, bufSize As Long
    bufSize = ExpandEnvironmentStrings(URL, ByVal 0&, 0&)
    buf = String(bufSize + 1, vbNullChar)
    bufSize = ExpandEnvironmentStrings(URL, buf, Len(buf))
    ExpandEnvironString = Left$(buf, InStr(1, buf, vbNullChar) - 1)
End Function

Before you call ShellApp(URL As String) you should expand the path:

URL = ExpandEnvironString(URL)

ShellExecute will receive the expanded path: C:\Users\AhmadMusa\AppData\Roaming\App3.exe

This is a non-breaking change, because if your initial default setting will be later changed to a custom fixed path, the ExpandEnvironmentStrings function will simply ignore it.

Example:

ExpandEnvironString("C:\App1.EXE ") will return C:\App1.EXE

More info:

you can get all your environment variables with following procedure:

Private Sub EnvironmentEntries()
    Dim Entry As String, i As Long
    i = 1
    Do
        Entry = Environ(i)
        i = i + 1
        If Entry = "" Then Exit Do
        Debug.Print Entry
    Loop
End Sub

... and check some additional info here:

Why are there directories called Local, LocalLow, and Roaming under \Users\?

deblocker
  • 7,629
  • 2
  • 24
  • 59
  • I dont want to get the AppData path by code (I already know how). I want to know what is the correct path to send to ShellExecute function run an executable file that is placed inside AppData. But not within the code. The idea is, as mentioned above, we have function to ShellExecute anything client want, and by default setup we want to run an App placed inside AppData, but client can change it later to be C:\App.exe, or D:\XXX\App.exe – Ahmad Mousa Jun 08 '17 at 16:00
  • prepend your command with "cmd /c " the "/c" part -might- be optional. – Bill Hileman Jun 08 '17 at 17:30
0
sub test()
    dim tmp as string
    tmp = environ("AppData ") & "\calc.exe"

    call  ShellExecute(..., tmp, ...)
end sub

fill the other arguments (...) the way you see it right

milevyo
  • 2,165
  • 1
  • 13
  • 18
0

I believe that there is no way to solve the problem without altering the original procedure "ShellApp".

in case you change your mind, i think this post may come in help (with some tweekings)

Public Sub ShellApp(URL As String)

        Dim vResult As Long
        'vResult = ShellExecute(0, vbNullString, URL, vbNullString, vbNullString, vbNormalFocus)
        vResult = ShellExecute(0, vbNullString, "cmd.exe", "/k """"" & URL & """""", vbNullString, vbNormalFocus)

End Sub

Private Sub Command1_Click()
    ShellApp "%appdata%\PROGRAME.exe"

End Sub

this because only "cmd.exe" and ofcourse batch scripts are able to expend variables that are enclosed with percent character "%"

To close the console as soon as it starts change the parameter "/k" to "/c",

milevyo
  • 2,165
  • 1
  • 13
  • 18
  • Thanks for the reply. I will see if I can use your above code to send it as URL initially to run cmd with exe path, without the update on function. Because updating the function requires a patch, and this patch shall be packaged for more than 500 different companies :) which is what am trying to avoid since beginning. Thanks anyway. – Ahmad Mousa Jun 14 '17 at 21:47