Announcement

Collapse
No announcement yet.

Shell question

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Scott Turchin
    replied
    Problem solved!
    This works on NT, I suspect it will work on 2000 and will test it tonight.

    The key was to run cscript.exe because CreateProcess *IS* looking for a .EXE to launch, so we use the script as a commandline parameter instead of assuming it is associated with Cscript.exe

    Cscript.exe is in 95/NT/ and 2000 by default.


    Code:
    '------------------------------------------------------------------------------------------
    'CreateShortCut bypasses coding COM in PB
    'Basically it writes a JScript and shells out and lets windows manage this.
    'This would be for use when say, it's a one time install and you don't need the
    'overhead of COM in your application etc.
    'ScriptName - Name the .JS script that will be written/run
    'TargetEXE  - The .EXE that the shortcut points to, include path
    'TargetStartDir - The "Start in" portion of the Link. Starting dir for your app.
    'TargetLNKName  - Name the link, do NOT add .LNK, the function will do this.
    'Status: Freeware - Use at your own risk
    'Scott Turchin
    'Computer Creations Software
    'http://www.tngbbs.com
    '------------------------------------------------------------------------------------------
    Function CreateShortCut(ByVal ScriptName As String, _
                            TargetEXE As String, _
                            TargetStartDir As String,_
                            TargetLNKName As String) As Long
    
    Dim St(1 To 10)         As String
    Local x                 As Long
    Local l_St              As String
    Local Start             As STARTUPINFO
    Local Proc              As PROCESS_INFORMATION
    
    Start.cb = SizeOf(Start)
    Start.dwFlags = %STARTF_USESHOWWINDOW
    Start.wShowWindow = 0
    
    Replace "\" With "\\" In TargetEXE
    Replace "\" With "\\" In TargetStartDir
    
    St(1)  = "var WSHShell = WScript.CreateObject(""WScript.Shell"");"
    St(2)  = "var DesktopPath = WSHShell.SpecialFolders(""Desktop"");"
    St(3)  = "var ShortCut = WSHShell.CreateShortcut(DesktopPath + " + Chr$(34) + "\\"  + TargetLNKName + ".LNK" + Chr$(34) + ");"
    St(4)  = "ShortCut.TargetPath = WSHShell.ExpandEnvironmentStrings(" + Chr$(34) + TargetEXE + Chr$(34) + ");"
    St(5)  = "ShortCut.WorkingDirectory = WSHShell.ExpandEnvironmentStrings(" + Chr$(34) + TargetStartDir + Chr$(34) + ");"
    St(6)  = "ShortCut.WindowStyle = 4;"
    St(7)  = "ShortCut.IconLocation = WSHShell.ExpandEnvironmentStrings(" + Chr$(34) + TargetExe + ", 0" + Chr$(34) + ");"  '0 indicates icon #
    St(8)  = "ShortCut.Save();"
    St(9)  = "WScript.Quit();"
    
    For x = 1 To 9
        l_St = l_St + St(x) + $CRLF
    Next
    Erase St
    x = FreeFile
    Open ScriptName For Output As #x
    Print #x, l_St
    Close x
    
    l_St = "cscript.exe " + ScriptName
    
    If CreateProcess("", _
                     ByVal StrPtr(l_St), _
                     ByVal %NULL, _
                     ByVal %NULL, _
                     0, _
                     %NORMAL_PRIORITY_CLASS, _
                     ByVal %NULL, _
                     ByVal %NULL, _
                     Start, _
                     proc) Then
    
              Call WaitForInputIdle(proc.hProcess, %INFINITE)
              Call WaitForSingleObject(proc.hProcess, %INFINITE)
              Call CloseHandle(proc.hProcess)
              Call CloseHandle(proc.hThread)
              Kill ScriptName
    End If
    Function = %TRUE
    End Function
    '------------------------------------------------------------------------------------------
    ------------------
    Scott
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Scott Turchin
    replied
    OK Baffled a bit.
    This works AWESOME on Win9x.

    However, on the 2000 server it fails, it fails to create a process...I put a msgbox in and an Else statement on the CreatProcess portion..
    I don't THINK I need permission to create a process, and there is no privilidge listed for this, or is there?

    Code:
    '------------------------------------------------------------------------------------------
    Function CreateShortCut(ByVal ScriptName As String, _
                            TargetEXE As String, _
                            TargetStartDir As String,_
                            TargetLNKName As String) As Long
    
    Dim St(1 To 10)         As String
    Local x                 As Long
    Local dwWaitCode        As Long
    Local l_St              As String
    Local zText             As Asciiz * 255
    Local Si As STARTUPINFO
    Local Pi As PROCESS_INFORMATION
    
    
    Si.cb = SizeOf(Si)
    Si.dwFlags = %STARTF_USESHOWWINDOW
    Si.wShowWindow = 0 'Invisible
    
    Replace "\" With "\\" In TargetEXE
    Replace "\" With "\\" In TargetStartDir
    
    St(1)  = "var WSHShell = WScript.CreateObject(""WScript.Shell"");"
    St(2)  = "var DesktopPath = WSHShell.SpecialFolders(""Desktop"");"
    St(3)  = "var ShortCut = WSHShell.CreateShortcut(DesktopPath + " + Chr$(34) + "\\"  + TargetLNKName + ".LNK" + Chr$(34) + ");"
    St(4)  = "ShortCut.TargetPath = WSHShell.ExpandEnvironmentStrings(" + Chr$(34) + TargetEXE + Chr$(34) + ");"
    St(5)  = "ShortCut.WorkingDirectory = WSHShell.ExpandEnvironmentStrings(" + Chr$(34) + TargetStartDir + Chr$(34) + ");"
    St(6)  = "ShortCut.WindowStyle = 4;"
    St(7)  = "ShortCut.IconLocation = WSHShell.ExpandEnvironmentStrings(" + Chr$(34) + TargetExe + ", 0" + Chr$(34) + ");"  '0 indicates icon #
    St(8)  = "ShortCut.Save();"
    St(9)  = "WScript.Quit();"
    
    For x = 1 To 9
        l_St = l_St + St(x) + $CRLF
    Next
    Erase St
    x = FreeFile
    Open ScriptName For Output As #x
    Print #x, l_St
    Close x
    'x = Shell(ScriptName,0)
    ScriptName = "start " + ScriptName
    If CreateProcess("", _
                     ByVal StrPtr(ScriptName), _
                     ByVal %NULL, _
                     ByVal %NULL, _
                     0, _
                     %NORMAL_PRIORITY_CLASS, _
                     ByVal %NULL, _
                     ByVal %NULL, _
                     Si, _
                     Pi) Then
           Call WaitForInputIdle(pi.hProcess, 250)
           Call WaitForSingleObjectEx(pi.hProcess, 1000,1) 'No more than one second
           Call CloseHandle(pi.hProcess)
           Call CloseHandle(pi.hThread)
    End If
    Kill ScriptName
    Function = %TRUE
    End Function
    '------------------------------------------------------------------------------------------

    ------------------
    Scott
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Scott Turchin
    replied
    I guess the end result is I will have to leave the script on the hard drive, which is not good...not clean at least...

    Thanks for the TIP on the 2000 box, I have a server and have done some testing, especially the InitiateSystemShutdown, but haven't gotten to test this yet since I can't even get it working properly on my 98 box


    I will have to check for the file when I check for the shortcut itself....

    Well, it's an emergency app anyway, guess it won't matter in this cae, but for future reference anybody got any ideas on this?


    I suspect WaitForSingleObject will come back into play here...


    Scott

    ------------------
    Scott
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Scott Turchin
    replied
    Thanks guys,
    I found that out about 30 seconds after I posted it but my cable modem has been up and down all night I couldn't get bakc up to clean this out ...

    It's still too strange either way though, using Shell xx,xx fails, using WaitForSingleObject is flaky, and using SLEEP 500 works just fine....


    I don't like it though, I'm going to use my Wait function that I wrote (Createprocess, waitforsingle object etc)....

    I don't HAVE to know this thing succeeded, but it would be nice...it's more like a shotgun blast in that I will do what I can to create it, but the primary purpose of this app is to shut the machine down as quickly as possible so waiting is not acceptable...


    Scott




    ------------------
    Scott
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Peter Amick
    replied
    Scott,

    There are two ways to use Shell, one is as a statement (such as "SHELL CmdString [, WndStyle]"), the other is as a function (as in "y = SHELL(CmdString [, WndStyle])"). While you're right that the Shell statement operates synchronously, in your code you are using a Shell function, which operates asynchronously. The following is a quote from the help file regarding the Shell function:
    "The Shell function runs other programs asynchronously. That means that you can not depend on a program started with Shell to be finished executing before the code following the Shell function in your code is executed. If your program ends before the Shelled program, the Shelled program will continue to run."

    By the way, on my system, running Win2000, your Shell function does not work. To get the code to work I switched to ShellExecute:

    STATIC zText As ASCIIZ * 128

    zText = ScriptName
    ShellExecute BYVAL %NULL, "open", zText, BYVAL %NULL, BYVAL %NULL, 0

    Haven't tried the Kill statement with it though.



    ------------------
    Peter Amick
    Baybuild Solutions

    Leave a comment:


  • Semen Matusovski
    replied
    Scott --
    "strange" is that you take the quote about SHELL statement, but use SHELL function.
    If you are ready to wait, you should write
    Shell ...
    Kill ...
    If not - put these statements in thread.

    ------------------

    Leave a comment:


  • Scott Turchin
    started a topic Shell question

    Shell question

    OK I'm doing the funky CreateShortcut code that I posted in the source code forum....

    I shell out and run the SHTCUT.JS script, life is good...

    But immediately after that, I do a KILL ScriptName (The above mentioned script)...

    Problem is, the KILL command happens right after the shell and the Help file states this about Shell:
    Note The Shell statement runs other programs synchronously. That means that execution of your code is suspended until the shelled program finishes.
    Now, that's all fine and dandy but my KILL was executing before the SHELL was complete, hence the file was deleted before it could get started.....

    Possibly something to do with the fact that windows has to run it and takes control of it, I don't know, just strange..

    Ideas?

    Here's the code, it seems to resolve itself if I put a WaitForSingleObject in place..

    Code:
    '------------------------------------------------------------------------------------------
    Function CreateShortCut(ScriptName As String, _
                            TargetEXE As String, _
                            TargetStartDir As String,_
                            TargetLNKName As String) As Long
    
    Dim St(1 To 10) As String
    Local x As Long
    Local l_St As String
    Replace "\" With "\\" In TargetEXE
    Replace "\" With "\\" In TargetStartDir
    Local dwMilliseconds As Long
    Local dwWaitCode     As Long
    dwMilliseconds = 250
    St(1)  = "var WSHShell = WScript.CreateObject(""WScript.Shell"");"
    St(2)  = "var DesktopPath = WSHShell.SpecialFolders(""Desktop"");"
    St(3)  = "var ShortCut = WSHShell.CreateShortcut(DesktopPath + " + Chr$(34) + "\\"  + TargetLNKName + ".LNK" + Chr$(34) + ");"
    St(4)  = "ShortCut.TargetPath = WSHShell.ExpandEnvironmentStrings(" + Chr$(34) + TargetEXE + Chr$(34) + ");"
    St(5)  = "ShortCut.WorkingDirectory = WSHShell.ExpandEnvironmentStrings(" + Chr$(34) + TargetStartDir + Chr$(34) + ");"
    St(6)  = "ShortCut.WindowStyle = 4;"
    St(7)  = "ShortCut.IconLocation = WSHShell.ExpandEnvironmentStrings(" + Chr$(34) + TargetExe + ", 0" + Chr$(34) + ");"  '0 indicates icon #
    St(8)  = "ShortCut.Save();"
    St(9)  = "WScript.Quit();"
    
    For x = 1 To 9
        l_St = l_St + St(x) + $CRLF
    Next
    Erase St
    x = FreeFile
    Open ScriptName For Output As #x
    Print #x, l_St
    Close x
    x = Shell("start " + ScriptName,0)
    Function = x
    Kill ScriptName
    End Function
    '------------------------------------------------------------------------------------------


    -------------
    Scott
    mailto:[email protected][email protected]</A>
Working...
X
😀
🥰
🤢
😎
😡
👍
👎