Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1643
  • Last Modified:

Running a Command Line program, VB6, ImageMagick

I'm using ImageMagick to convert some files.  When I do Start->Run->cmd

and then type C:\convert logo.gif logo.jpg

It does the conversion fine.

But in VB6 when I issue Shell("convert logo.gif logo.jpg") it doesn't convert, as expected.
0
hrolsons
Asked:
hrolsons
  • 6
  • 3
  • 3
  • +3
2 Solutions
 
GeoffHarperCommented:
Try using the code below; it will wait for the program to terminate.
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Function ExecuteCommand(ByVal Appl As String, Optional ByVal stdout_file As String = "", Optional ByVal stderr_file As String = "") As Long
    Dim objShell, objWshScriptExec, objStdOut, objStdErr
    Dim StdOutBuf As String, StdErrBuf As String
    Dim FN As Integer
    Dim Completed As Boolean
    
    Set objShell = CreateObject("WScript.Shell")
    Set objWshScriptExec = objShell.Exec(Appl)
    
    Do While objWshScriptExec.Status = 0
        Sleep 100
        DoEvents
    Loop

    StdOutBuf = objWshScriptExec.StdOut.ReadAll
    StdErrBuf = objWshScriptExec.StdErr.ReadAll
    
    If stdout_file <> "" Then
        FN = FreeFile
        Open stdout_file For Binary Access Write As #FN
        Put #FN, , StdOutBuf
        Close #FN
    End If
    
    If stderr_file <> "" Then
        FN = FreeFile
        Open stderr_file For Binary Access Write As #FN
        Put #FN, , StdErrBuf
        Close #FN
    End If
    
    ExecuteCommand = 0
    
End Function

Open in new window

0
 
hrolsonsAuthor Commented:
GeoffHarper:  The code didn't seem to work.  I inserted what you listed and then called:

ExecuteCommand ("convert logo.gif logo.jpg")

And it didn't do the conversion.  Is that how I should call it?
0
 
HooKooDooKuCommented:
Have you tried "C:\convert logo.gif logo.jpg" with Shell or ExecuteCommand?

You indicated that you included the 'C:\' when you executed from the command line, but you are leaving it out with Shell.

When you don't specify the path of an executable, the system looks in the current working folder, then the list of folders in the environment variable PATH.  Typically "C:\" isn't included in the PATH.

I'll also point out that when you run 'cmd', the default working folder is (on my XP machine) is "C:\Documents and Settings\MyUserID".  So I'm going to assume that is where logo.gif is located.  When you run VB from the ide, the default working folder is what ever the default working folder of VB is (unlikely to be the Documents and settings).  Therefore you might still run into an issue simply adding "C:\" in front of "convert" because the convert program might not be able to find "logo.gif".  

So the properly get the application running, you might need to include a full path for both the EXE and the input file.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
khairilCommented:
Hi,

This the way to go, change the working path to reflect yours:

Option Explicit

Private Declare Function ShellExecute Lib "shell32.dll" Alias _
 "ShellExecuteA" (ByVal hWnd As Long, ByVal lpOperation As _
 String, ByVal lpFile As String, ByVal lpParameters As String, _
 ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
 
'Useage:
Private Sub Form_Load()
 Dim sWorkingPath As String
 
 sWorkingPath = "C:\Users\khairil\Desktop\ImageMagick-6.7.2-8\"
 Call ShellExecute(0, "Open", FilePath & "convert.exe", "logo.gif logo.jpg", sWorkingPath, 0)
End Sub

Open in new window



0
 
khairilCommented:
Opps error line 13, it should be sWorkingPath not FilePath:

Here the fix:

Option Explicit

Private Declare Function ShellExecute Lib "shell32.dll" Alias _
 "ShellExecuteA" (ByVal hWnd As Long, ByVal lpOperation As _
 String, ByVal lpFile As String, ByVal lpParameters As String, _
 ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
 
'Useage:
Private Sub Form_Load()
 Dim sWorkingPath As String
 
 sWorkingPath = "C:\Users\khairil\Desktop\ImageMagick-6.7.2-8\"
 Call ShellExecute(0, "Open", sWorkingPath & "convert.exe", "logo.gif logo.jpg", sWorkingPath, 0)
End Sub

Open in new window

0
 
hrolsonsAuthor Commented:
HooKooDooKu:  Right, I left all the directory stuff out to avoid confusion.

khairil:  Didn't work for me.
0
 
kbireckiCommented:
I've done a lot of this.  I had the same problem.. I found that the must reliable way to do this is to write my commands to a batch file and then use ShellAndWait to execute the batch file, then delete the batch file.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Try wrapping the exe in quotes:

    Shell(Chr(34) & "FullPathToConvertInHere" & Chr(34) & " " & logo.gif logo.jpg")

If the path to "logo" involves spaces, then you might need to individually wrap those to.
0
 
GeoffHarperCommented:
Sorry, I got totally sidetracked by work.

If you use my original code I posted and put in the path of the "convert" executable it should work.

I.e.

     ExecuteCommand "C:\convert.exe C:\logo.gif C:\logo.jpg"

that would be if the executable and the files are in the root directory "C:\"
0
 
hrolsonsAuthor Commented:
I shouldn't have to do all these "tricks", it seems to me, because convert.exe is in my Windows PATH.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Sometimes the system has trouble differentiating between what is the path & executable and what is a path & parameter.  Adding the quotes can make it clear to the system which is which.
0
 
khairilCommented:
Hi,

I have tested my code, and it works. You need to ensure that your enter the correct path for WorkingPath. WorkingPath is where the convert.exe is, but only the path.

If you image is not in the same path as WorkingPath then you need to put full path of the image so it will be. Notice for any white space in the path so that you not encouter any error :

Call ShellExecute(0, "Open", sWorkingPath & "convert.exe", "c:\temp\logo.gif c:\newlocation\logo.jpg", sWorkingPath, 0)

Open in new window


Hope this works for you. Using this way you do not need to declare any environmental PATH when deploy to client.
0
 
khairilCommented:
Here is my test code. You just need to do:

1. Compile the file into exe
2. Copy convert.exe into the directory of exe you build above
3. Ensure that image location is valid
4. Run the exe.
convert-test.zip
0
 
khairilCommented:
I not supplying convert.exe because it is big (~5MB) and security concern.
0
 
kbireckiCommented:
@hrolsons, You're executing a non-native DOS app, so you have to jump through some hoops.  Idle_Mind is right about the need for quotes.

Whatever solution you choose, be sure to consider that ImageMagick will take time to execute,  especially as you perform more complex IM commands.  It will be more time than it takes VB6 to execute the ShellExecute command and continue on.  I trust that khairil's solution will work, but ShellExecute will execute immediately and continue to the next vb6 line in code and if anything depends on the result from your IM command, then it's likely your IM result may not be ready if you have subsequent processing on or with the resulting file.  You should consider using ShellAndWait (attached) to make sure ImageMagick is done before any subsequent processing.  

The solution I used may not be the best solution, but I write a series of commands to a batch file and ShellAndWait for it to finish because it seemed better than a series of ShellAndWaits where VB6 had to, each time, bounce out to start a new DOS program instead of only once for a single batch file.  It just worked better for me.  I don't know the inner workings of ShellExecute, but I'm assuming it has to setup a whole DOS environment each time it executes, otherwise it wouldn't have access to the whole DOS environment, such as the System path, which can change through the course of an application execution, so I treat it as overhead that I chose to run once per image processing session versus once per image processing command.

However, you can get the ShellExecute concept to work, just consider the time.  Or consider using the attached ShellAndWait that I modified from a couple sources online (referenced in the source code.)  It uses the same parameters as ShellExecute, so it would be a drop-in replacement.
basShellAndWait.bas
0
 
khairilCommented:
What kbirecki said is right about waiting. You can try his solution. I have one addressing same problem, I do not know if this code works for you or not: http://www.vbaccelerator.com/home/vb/code/libraries/Shell_Projects/Shell_And_Wait_For_Completion/article.asp


0
 
kbireckiCommented:
These are all good solutions.  Isn't programming awesome!?!  That there are many different ways to achieve the same or similar results is one of the reasons I fell in love with computers.  And I'm hooked on picking up new tips and tricks from all you other experts.  I for one appreciate all your participation on e-e.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 6
  • 3
  • 3
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now