Problems using ShellExecute

Hi guys,
I'm having problems using "ShellExecute" in VB.NET. In using ShellExecute I only need to specify target file and the OS will work out which application to use to open the specified file. For my example below I get target application run and open the supplied file however I get an error (in the calling VB.NET application) indicating unbalanced stack, suggesting inappropriate parameters supplied to ShellExecute. I tried a few variations but get similar/worse results.

What am I doing wrong in the code below?

Dim R As Long
Dim Scr_hDC As Long = GetDesktopWindow()
R = ShellExecute(Scr_hDC, TargetFileName, "Open", vbNullString, vbNullString, SW_SHOWNORMAL)


P.S. In my VB6 application I used:
R = ShellExecute(Scr_hDC, "Open", TargetFileName, "", TargetDirpath, SW_SHOWNORMAL)
and that worked for me but not for VB.NET.
Who is Participating?
SStoryConnect With a Mentor Commented:
Here's how:

        Dim psi As New ProcessStartInfo(filename, args)
        psi.WindowStyle = ProcessWindowStyle.Normal
        psi.WorkingDirectory = "whateverdir"

        Dim p As New Process
        p.StartInfo = psi
mastooConnect With a Mentor Commented:
You'll be better off switching to use the .Net Process class to start the process.
Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
Or you can just use:

    Process.Start("c:\yourfilepathwithextensionhere") ' <--- opens the file with the associated application...

But to answer your question, you get an "unbalanced stack" error because you are using a VB6 API declaration in a VB.Net app.  Change the declaration so that all occurences of "Long" are changed to "Integer" and the problem will go away...
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

good point Idle_Mind, the declaration long vs. integer is a common gotcha.

it is true that you can just do Process.Start
If you want more control you declare the ProcessStartInfo class as I showed you before.  Both are valid.
gem56Author Commented:
Hi guys,
The appropriate application opens the file however I'm not able to pass any arguments to the application, using both SStory and Idle_Mind approach:
       Process.Start(TargetFileName, " nosplash")
       Process.Start(TargetFileName, " ,nosplash")
       Process.Start(TargetFileName, " \nosplash")

To check what's coming in to the (VB6 based) target application I placed the following statement in that application:
       MsgBox "Command line >" & Command & "<"

And the mesage that I get is:   Command line >C:\.........\FileName.ext,open<
It seems that 'Process' inserts the 'open' parameter but doesn't pass on 'nosplash'.

Any ideas as to why?

Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
Try the verbose method SStory showed earlier, but specify the application exe as well, and pass the filename via the arguments parameter:

        Dim psi As New ProcessStartInfo
        psi.FileName = "c:\someApplication.exe"
        psi.Arguments = TargetFileName & " ,nosplash"

Otherwise, not sure....
gem56Author Commented:
Yes Bob that's worked, although it half defeated the purpose as I didn't want to have to find the Target application. It appears that if an executable is supplied then it assumes action to be 'open' and doesn't let you enter parameters. If however you enter the executable as the file then (as you suggested) the actual document file name is/can be specified as a parameter.

That being the case, is there an easy way of determining what application will process a particular document type?

P.S. I've bumped up the points.
Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
What a pain in the patookee eh?...

Here is an approach that determines the associated EXE with a given file extension using the FindExecutable() API:

    Private Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" _
        (ByVal lpFile As String, ByVal lpDirectory As String, _
        ByVal lpResult As System.Text.StringBuilder) As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Const MAX_PATH As Integer = 260
        Dim FileName As String = "c:\test.xls"
        If System.IO.File.Exists(FileName) Then
            Dim AssociatedEXE As New System.Text.StringBuilder(MAX_PATH)
            FindExecutable(FileName, vbNullString, AssociatedEXE)
            If AssociatedEXE.Length > 0 Then
                MessageBox.Show("Associated EXE: " & AssociatedEXE.ToString(), FileName, MessageBoxButtons.OK, MessageBoxIcon.Information)
                MessageBox.Show("No Associated EXE found.", FileName, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
            MessageBox.Show(FileName, "File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Sub
gem56Author Commented:
That's excellent, as always. ;-)
gem56Author Commented:
Thanks everyone.
gem56Author Commented:
Sorry guys I forgot one thing.
After creating the window using code above (and saving 'p' outside the function), how can I subsequently place that window in the foreground?
I tried the statement below but that doesn't work. How can I place a window in foreground?


Mike TomlinsonMiddle School Assistant TeacherCommented:
Use "p.MainWindowHandle" instead of "p.Handle"
gem56Author Commented:
Once again, that's done it so thanks a lot.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.