Announcement

Collapse
No announcement yet.

Shell question

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

  • 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>
    Scott Turchin
    MCSE, MCP+I
    http://www.tngbbs.com
    ----------------------
    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

  • #2
    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.

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

    Comment


    • #3
      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
      Peter Amick
      Baybuild Solutions

      Comment


      • #4
        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>
        Scott Turchin
        MCSE, MCP+I
        http://www.tngbbs.com
        ----------------------
        True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

        Comment


        • #5
          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>
          Scott Turchin
          MCSE, MCP+I
          http://www.tngbbs.com
          ----------------------
          True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

          Comment


          • #6
            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>
            Scott Turchin
            MCSE, MCP+I
            http://www.tngbbs.com
            ----------------------
            True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

            Comment


            • #7
              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>
              Scott Turchin
              MCSE, MCP+I
              http://www.tngbbs.com
              ----------------------
              True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

              Comment

              Working...
              X
              😀
              🥰
              🤢
              😎
              😡
              👍
              👎