Solved

cannot run external program with re-direction parameter ">logfile.txt"

Posted on 2003-11-25
14
1,185 Views
Last Modified: 2010-04-16
Hi Guys,

I'm trying to call gfix.exe(Interbase utility) from Delphi application to shut down my database(I need to backup it afterwards). To get results of running gfix.exe I use syntax like this:

run := 'C:\progra~1\firebird\firebi~1\bin\gfix.exe -shut -force 30 c:\totalpak\data\newfarm.gdb -user duduser -pass fakepassword 2> c:\errout.tm';
RunAndWait32(run, sw_hide);

RunAndWait32 is a quite common procedure using CreateProcess and WaitForSingleObject.

It doesn't work this way and does not redirect gfix output to errout.tm.

If I put RUN string into bat file and then do: RunAndWait32('mybatfile.bat', sw_hide) it doesn't work either(does not create errout.tm file). But if I run this bath file from within windows environment it works just fine.

Anyone has any clues ?

Cheers,
Dmitry
0
Comment
Question by:Trekker72
  • 5
  • 4
  • 3
  • +1
14 Comments
 
LVL 5

Expert Comment

by:snehanshu
Comment Utility
Can you provide your code of RunAndWait32?
...Shu
0
 
LVL 2

Author Comment

by:Trekker72
Comment Utility
Here it is:

function WinExecAndWait32(Path: PChar; Visibility: Word;
  Timeout : DWORD): integer;
var
  WaitResult : integer;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  iResult : integer;
begin
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  with StartupInfo do
  begin
    cb := SizeOf(TStartupInfo);
    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
      { you could pass sw_show or sw_hide as parameter: }
    wShowWindow := visibility;
  end;
  if CreateProcess(nil,path,nil, nil, False,
            NORMAL_PRIORITY_CLASS, nil, nil,
            StartupInfo, ProcessInfo) then
  begin
    WaitResult := WaitForSingleObject(ProcessInfo.hProcess, timeout);
    { timeout is in miliseconds or INFINITE if
        you want to wait forever }
    result := WaitResult;
  end
  else
  { error occurs during CreateProcess see help for details }
    result:=GetLastError;
end;
0
 
LVL 2

Author Comment

by:Trekker72
Comment Utility
I invoke RunAndWait32(PChar(run), sw_hide, 50000);

Cheers
Dmity aka Terry

0
 
LVL 5

Expert Comment

by:snehanshu
Comment Utility
Well WinExecAndWait32 looks fine and I have no clue then.
Perhaps something to do with how gfix.exe works, which I don't have.
I hope some experts see this Q and help.
Good luck,
...Shu
0
 
LVL 2

Author Comment

by:Trekker72
Comment Utility
I did not mention that my application is a service one. So I invoke RunAndWait32 from TService, if it does make any difference.

Thanks Shu, anyway

Cheers
0
 
LVL 5

Expert Comment

by:snehanshu
Comment Utility
Trekker72,
Well then, here are a few guesses:
I trued writing a simple app where I created a batch file gfix.bat containing the following:

@echo %1 %2 %3 %4 %5 %6 %7 %8 %9
@dir c:\*.*
then, in my application, I added the following code:

procedure TForm1.Button1Click(Sender: TObject);
Var
  Run: String;
begin
  run := 'C:\progra~1\firebird\firebi~1\bin\gfix.bat -shut -force 30 c:\totalpak\data\newfarm.gdb -user duduser -pass fakepassword 2 > c:\errout.txt';
  ShowMessage(format('Error = %d',[WinExecAndWait32(pchar(run),sw_show, 5000)]));
end;

Then, I did get a text file "c:\errout.txt" as expected.

You could also try this replacing the batch with the exe in a simple app and see whether you get the output file. If you don't, then the problem is perhaps with the way gfix.exe works.

If you do, then check that your service's interactive property is set to true (To allow it to interact with the desktop).
These are just guesses, I hope they help.
...Shu
0
 
LVL 2

Author Comment

by:Trekker72
Comment Utility
Thanks Shu,

I think you're right it is all about the way gfix.exe works.
Now I get it working(I used some other execandwait function) but it always says "unavailable database".
I get the same error message if I run gbak.exe.
If I run it as normal GUI application it works fine. I set service's interactive property to true but it did not help.

Cheers
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 5

Assisted Solution

by:snehanshu
snehanshu earned 125 total points
Comment Utility
>>If I run it as normal GUI application it works fine. I set service's interactive property to true but it did not help.
You mean the same code works in a normal app but not from a service?
Perhaps you could try to manually check the "allow service to interact with desktop" checkbox in your service's properties (logon, from service manager) or try uninstalling and reinstalling the service after compiling it with the interactive property set t true.
...Shu
0
 
LVL 17

Accepted Solution

by:
geobul earned 125 total points
Comment Utility
Hi,

Try setting your service to logon using your account instead of the default 'Local System Account'. Stop it first, open its properties, change the logon account and start it again.

The problem is in access rights (security issue) I think.

Regards, Geo
0
 
LVL 17

Expert Comment

by:geobul
Comment Utility
BTW. I use this:

    GetExitCodeProcess(ProcessInfo.hProcess, Result);
    CloseHandle(ProcessInfo.hProcess); // you must close these two handles
    CloseHandle(ProcessInfo.hThread);

instead of your

result := WaitResult;

in order to obtain the result code of the executed process.
0
 
LVL 6

Expert Comment

by:GloomyFriar
Comment Utility
I'm not sure, but try to set CREATE_NEW_CONSOLE flag:
dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK or CREATE_NEW_CONSOLE;
0
 
LVL 6

Expert Comment

by:GloomyFriar
Comment Utility
If the flag will not help you need to redirect child process streams.
Ho to do that read here:
http://oldlook.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20610325.html
0
 
LVL 6

Expert Comment

by:GloomyFriar
Comment Utility
0
 
LVL 2

Author Comment

by:Trekker72
Comment Utility
Guys,

problem solved by putting localhost: in front of db name like this: gbak -b localhost:c:\mydb.gdb c:\mydb.gbk
As I mentioned before, gbak worked fine if I run it without localhost: from GUI. For Service application don't forget about localhost: !!!
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video discusses moving either the default database or any database to a new volume.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now