Monday, December 25, 2017

http://wiki.freepascal.org/Executing_External_Programs#MS_Windows_:_CreateProcess.2C_ShellExecute_and_WinExec






---------

Overview : Comparison

Here are different ways available in RTL, FCL and LCL libraries on how to execute an external command/process/program.
MethodLibraryPlatformsSingle LineFeatures
ExecuteProcessRTLCross-PlatformYesVery limited, synchronous
ShellExecuteWinAPIMS Windows onlyYesMany. Can start programs with elevation/admin permissions.
fpsystem, fpexecveUnixUnix only
TProcessFCLCross-PlatformNoFull
RunCommandFCLCross-Platform Requires FPC 2.6.2+YesCovers common TProcess usage
OpenDocumentLCLCross-PlatformYesOnly open document. The document would open with the application associated with that type of the document.

(Process.)RunCommand

In FPC 2.6.2, some helper functions for TProcess were added to unit process based on wrappers used in the fpcup project. These functions are meant for basic and intermediate use and can capture output to a single string and fully support the large output case.
A simple example is
uses Process;
...
var s : ansistring;
...
if RunCommand('/bin/bash',['-c','echo $PATH'],s) then
   writeln(s);
An overloaded variant of RunCommand returns the exitcode of the program. The RunCommandInDir runs the command in a different directory (sets p.CurrentDirectory):
function RunCommandIndir(const curdir:string;const exename:string;const commands:array of string;var outputstring:string; var exitstatus:integer): integer;
function RunCommandIndir(const curdir:string;const exename:string;const commands:array of string;var outputstring:string): boolean;
function RunCommand(const exename:string;const commands:array of string;var outputstring:string): boolean;

SysUtils.ExecuteProcess

(Cross-platform)
Despite a number of limitations, the simplest way to launch a program (modal, no pipes or any form of control) is to simply use :
SysUtils.ExecuteProcess(UTF8ToSys('/full/path/to/binary'), '', []);
The calling process runs synchronously: it 'hangs' until the external program has finished - but this may be useful if you require the user to do something before continuing in your application. For a more versatile approach, see the next section about the prefered cross-platform TProcess, or if you only wish to target Windows you may use ShellExecute.

MS Windows : CreateProcess, ShellExecute and WinExec

Note-icon.png
Note: While FPC/Lazarus has support for CreateProcessShellExecute and/or WinExec, this support is only in Win32/64. If your program is cross-platform, consider using RunCommand or TProcess.
Note-icon.png
Note: WinExec is a 16-bit call that has been deprecated for years in the Windows API. In recent versions of FPC it generates a warning.
ShellExecute is a standard MS Windows function (ShellApi.h) with good documentation on MSDN (note their remarks about initialising COM if you find the function unreliable).
uses ..., ShellApi;
 
// Simple one-liner (ignoring error returns) :
if ShellExecute(0,nil, PChar('"C:\my dir\prog.exe"'),PChar('"C:\somepath\some_doc.ext"'),nil,1) =0 then;
 
// Execute a Batch File :
if ShellExecute(0,nil, PChar('cmd'),PChar('/c mybatch.bat'),nil,1) =0 then;
 
// Open a command window in a given folder :
if ShellExecute(0,nil, PChar('cmd'),PChar('/k cd \path'),nil,1) =0 then;
 
// Open a webpage URL in the default browser using 'start' command (via a brief hidden cmd window) :
if ShellExecute(0,nil, PChar('cmd'),PChar('/c start www.lazarus.freepascal.org/'),nil,0) =0 then;
 
// or a useful procedure:
procedure RunShellExecute(const prog,params:string);
begin
  //  ( Handle, nil/'open'/'edit'/'find'/'explore'/'print',   // 'open' isn't always needed 
  //      path+prog, params, working folder,
  //        0=hide / 1=SW_SHOWNORMAL / 3=max / 7=min)   // for SW_ constants : uses ... Windows ...
  if ShellExecute(0,'open',PChar(prog),PChar(params),PChar(extractfilepath(prog)),1) >32 then; //success
  // return values 0..32 are errors
end;
There is also ShellExecuteExW as a WideChar version, and ShellExecuteExA is AnsiChar.
The fMask option can also use SEE_MASK_DOENVSUBST or SEE_MASK_FLAG_NO_UI or SEE_MASK_NOCLOSEPROCESS, etc.
If in Delphi you used ShellExecute for documents like Word documents or URLs, have a look at the open* (openurl etc) functions in lclintf (see the Alternatives section lower down this page).

Using ShellExecuteEx for elevation/administrator permissions

If you need to execute external program with administrator/elevated privileges, you can use the runas method with the alternative ShellExecuteEx function:
uses ShellApi, ...;
 
function RunAsAdmin(const Handle: Hwnd; const Path, Params: string): Boolean;
var
  sei: TShellExecuteInfoA;
begin
  FillChar(sei, SizeOf(sei), 0);
  sei.cbSize := SizeOf(sei);
  sei.Wnd := Handle;
  sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
  sei.lpVerb := 'runas';
  sei.lpFile := PAnsiChar(Path);
  sei.lpParameters := PAnsiChar(Params);
  sei.nShow := SW_SHOWNORMAL;
  Result := ShellExecuteExA(@sei);
end;
 
procedure TFormMain.RunAddOrRemoveApplication;
begin
  // Example that uses elevated rundll to open the Control Panel to Programs and features
  RunAsAdmin(FormMain.Handle, 'rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl', '');
end;

Unix fpsystem, fpexecve and shell

These functions are platform dependent.
Note that the 1.0.x 'Unix.Shell has been deprecated for a while, and is removed in trunk. Use fpsystem.

TProcess

You can use TProcess to launch external programs. Some of the benefits of using TProcess are that it is:
  • Platform Independent
  • Capable of reading from stdout and writing to stdin.
  • Possible to wait for a command to finish or let it run while your program moves on.
Important notes:
  • TProcess is not a terminal/shell! You cannot directly execute scripts or redirect output using operators like "|", ">", "<", "&" etc. It is possible to obtain the same results with TProcess using pascal, some examples are below..
  • Presumably on Linux/Unix: you must specify the full path to the executable. For example '/bin/cp' instead of 'cp'. If the program is in the standard PATH then you can use the function FindDefaultExecutablePath from the FileUtil unit of the LCL.
  • On Windows, if the command is in the path, you don't need to specify the full path.
  • TProcess reference

The Simplest Example

A lot of typical cases have been prepared in the Runcommand functions. Before you start copy and paste the examples below, check them out first.

A Simple Example

This example (that shouldn't be used in production, see Large Output or, better, Runcommand) just shows you how to run an external program, nothing more:
// This is a demo program that shows
// how to launch an external program.
program launchprogram;
 
// Here we include files that have useful functions
// and procedures we will need.
uses 
  Classes, SysUtils, Process;
 
// This defines the var "AProcess" as a variable 
// of the type "TProcess"
var 
  AProcess: TProcess;
 
// This is where our program starts to run
begin
  // Now we will create the TProcess object, and
  // assign it to the var AProcess.
  AProcess := TProcess.Create(nil);
 
  // Tell the new AProcess what the command to execute is.
  // Let's use the Free Pascal compiler (i386 version that is)
  AProcess.Executable:= 'ppc386';
 
  // Pass -h together with ppc386 so actually 'ppc386 -h' is executed:
  AProcess.Parameters.Add('-h');
 
  // We will define an option for when the program
  // is run. This option will make sure that our program
  // does not continue until the program we will launch
  // has stopped running.                vvvvvvvvvvvvvv
  AProcess.Options := AProcess.Options + [poWaitOnExit];
 
  // Now let AProcess run the program
  AProcess.Execute;
 
  // This is not reached until ppc386 stops running.
  AProcess.Free;   
end.
That's it! You have just learned to run an external program from inside your own program.

An improved example (but not correct yet)

That's nice, but how do I read the Output of a program that I have run?
Well, let's expand our example a little and do just that: This example is kept simple so you can learn from it. Please don't use this example in production code, but use the code in #Reading large output.
// This is a 
// FLAWED
// demo program that shows
// how to launch an external program
// and read from its output.
program launchprogram;
 
// Here we include files that have useful functions
// and procedures we will need.
uses 
  Classes, SysUtils, Process;
 
// This is defining the var "AProcess" as a variable 
// of the type "TProcess"
// Also now we are adding a TStringList to store the 
// data read from the programs output.
var 
  AProcess: TProcess;
  AStringList: TStringList;
 
// This is where our program starts to run
begin
  // Now we will create the TProcess object, and
  // assign it to the var AProcess.
  AProcess := TProcess.Create(nil);
 
  // Tell the new AProcess what the command to execute is.
  AProcess.Executable := '/usr/bin/ppc386'; 
  AProcess.Parameters.Add('-h'); 
 
  // We will define an option for when the program
  // is run. This option will make sure that our program
  // does not continue until the program we will launch
  // has stopped running. Also now we will tell it that
  // we want to read the output of the file.
  AProcess.Options := AProcess.Options + [poWaitOnExit, poUsePipes];
 
  // Now that AProcess knows what the commandline is it can be run.
  AProcess.Execute;
 
  // After AProcess has finished, the rest of the program will be executed.
 
  // Now read the output of the program we just ran into a TStringList.
  AStringList := TStringList.Create;
  AStringList.LoadFromStream(AProcess.Output);
 
  // Save the output to a file and clean up the TStringList.
  AStringList.SaveToFile('output.txt');
  AStringList.Free;
 
  // Now that the output from the process is processed, it can be freed.
  AProcess.Free;   
end.

Reading large output

In the previous example we waited until the program exited. Then we read what the program has written to its output.
Suppose the program writes a lot of data to the output. Then the output pipe becomes full and the called progam waits until the pipe has been read from.
But the calling program doesn't read from it until the called program has ended. A deadlock occurs.
The following example therefore doesn't use poWaitOnExit, but reads from the output while the program is still running. The output is stored in a memory stream, that can be used later to read the output into a TStringList.
If you want to read output from an external process, this is the code you should adapt for production use.
program LargeOutputDemo;
 
{$mode objfpc}{$H+}
 
uses
  Classes, SysUtils, Process; // Process is the unit that holds TProcess
 
const
  BUF_SIZE = 2048; // Buffer size for reading the output in chunks
 
var
  AProcess     : TProcess;
  OutputStream : TStream;
  BytesRead    : longint;
  Buffer       : array[1..BUF_SIZE] of byte;
 
begin
  // Set up the process; as an example a recursive directory search is used
  // because that will usually result in a lot of data.
  AProcess := TProcess.Create(nil);
 
  // The commands for Windows and *nix are different hence the $IFDEFs
  {$IFDEF Windows}
    // In Windows the dir command cannot be used directly because it's a build-in
    // shell command. Therefore cmd.exe and the extra parameters are needed.
    AProcess.Executable := 'c:\windows\system32\cmd.exe';
    AProcess.Parameters.Add('/c');
    AProcess.Parameters.Add('dir /s c:\windows');
  {$ENDIF Windows}
 
  {$IFDEF Unix}
    AProcess.Executable := '/bin/ls';
    AProcess.Parameters.Add('--recursive');
    AProcess.Parameters.Add('--all');
    AProcess.Parameters.Add('-l');
  {$ENDIF Unix}
 
  // Process option poUsePipes has to be used so the output can be captured.
  // Process option poWaitOnExit can not be used because that would block
  // this program, preventing it from reading the output data of the process.
  AProcess.Options := [poUsePipes];
 
  // Start the process (run the dir/ls command)
  AProcess.Execute;
 
  // Create a stream object to store the generated output in. This could
  // also be a file stream to directly save the output to disk.
  OutputStream := TMemoryStream.Create;
 
  // All generated output from AProcess is read in a loop until no more data is available
  repeat
    // Get the new data from the process to a maximum of the buffer size that was allocated.
    // Note that all read(...) calls will block except for the last one, which returns 0 (zero).
    BytesRead := AProcess.Output.Read(Buffer, BUF_SIZE);
 
    // Add the bytes that were read to the stream for later usage
    OutputStream.Write(Buffer, BytesRead)
 
  until BytesRead = 0;  // Stop if no more data is available
 
  // The process has finished so it can be cleaned up
  AProcess.Free;
 
  // Now that all data has been read it can be used; for example to save it to a file on disk
  with TFileStream.Create('output.txt', fmCreate) do
  begin
    OutputStream.Position := 0; // Required to make sure all data is copied from the start
    CopyFrom(OutputStream, OutputStream.Size);
    Free
  end;
 
  // Or the data can be shown on screen
  with TStringList.Create do
  begin
    OutputStream.Position := 0; // Required to make sure all data is copied from the start
    LoadFromStream(OutputStream);
    writeln(Text);
    writeln('--- Number of lines = ', Count, '----');
    Free
  end;
 
  // Clean up
  OutputStream.Free;
end.
Note that the above could also be accomplished by using RunCommand:
var s: string;
...
RunCommand('c:\windows\system32\cmd.exe', ['/c', 'dir /s c:\windows'], s);

Using input and output of a TProcess

See processdemo example in the Lazarus-CCR SVN.

Hints on the use of TProcess

When creating a cross-platform program, the OS-specific executable name can be set using directives "{$IFDEF}" and "{$ENDIF}".
Example:
{...}
AProcess := TProcess.Create(nil)
 
{$IFDEF WIN32}
  AProcess.Executable := 'calc.exe'; 
{$ENDIF}
 
{$IFDEF LINUX}
  AProcess.Executable := FindDefaultExecutablePath('kcalc');
{$ENDIF}
 
AProcess.Execute;
{...}

OS X show application bundle in foreground

You can start an application bundle via TProcess by starting the executable within the bundle. For example:
 AProcess.Executable:='/Applications/iCal.app/Contents/MacOS/iCal';
This will start the Calendar, but the window will be behind the current application. To get the application in the foreground you can use the open utility with the -n parameter:
 AProcess.Executable:='/usr/bin/open';
 AProcess.Parameters.Add('-n');
 AProcess.Parameters.Add('-a'); //optional: to hide terminal - similar to Windows option poNoConsole
 AProcess.Parameters.Add('/Application/iCal.app');
If your application needs parameters, you can pass open the --args parameter, after which all parameters are passed to the application:
 AProcess.Parameters.Add('--args');
 AProcess.Parameters.Add('argument1');
 AProcess.Parameters.Add('argument2');

Run detached program

Normally a program started by your application is a child process and is killed, when your application is killed. When you want to run a standalone program that keeps running, you can use the following:
var
  Process: TProcess;
  I: Integer;
begin
  Process := TProcess.Create(nil);
  try
    Process.InheritHandles := False;
    Process.Options := [];
    Process.ShowWindow := swoShow;
 
    // Copy default environment variables including DISPLAY variable for GUI application to work
    for I := 1 to GetEnvironmentVariableCount do
      Process.Environment.Add(GetEnvironmentString(I));
 
    Process.Executable := '/usr/bin/gedit';  
    Process.Execute;
  finally
    Process.Free;
  end;
end;

Example of "talking" with aspell process

Inside pasdoc source code you can find two units that perform spell-checking by "talking" with running aspell process through pipes:
  • PasDoc_ProcessLineTalk.pas unit implements TProcessLineTalk class, descendant of TProcess, that can be easily used to talk with any process on a line-by-line basis.
  • PasDoc_Aspell.pas units implements TAspellProcess class, that performs spell-checking by using underlying TProcessLineTalk instance to execute aspell and communicate with running aspell process.
Both units are rather independent from the rest of pasdoc sources, so they may serve as real-world examples of using TProcess to run and communicate through pipes with other program.

Replacing shell operators like "| < >"

Sometimes you want to run a more complicated command that pipes its data to another command or to a file. Something like
ShellExecute('firstcommand.exe | secondcommand.exe');
or
ShellExecute('dir > output.txt');
Executing this with TProcess will not work. i.e:
// this won't work
Process.CommandLine := 'firstcommand.exe | secondcommand.exe'; 
Process.Execute;

Why using special operators to redirect output doesn't work

TProcess is just that, it's not a shell environment, only a process. It's not two processes, it's only one. It is possible to redirect output however just the way you wanted. See the next section.

How to redirect output with TProcess

You can redirect the output of a command to another command by using a TProcess instance for each command.
Here's an example that explains how to redirect the output of one process to another. To redirect the output of a process to a file/stream see the example Reading Large Output
Not only can you redirect the "normal" output (also known as stdout), but you can also redirect the error output (stderr), if you specify the poStderrToOutPut option, as seen in the options for the second process.
program Project1;
 
uses
  Classes, sysutils, process;
 
var
  FirstProcess,
  SecondProcess: TProcess;
  Buffer: array[0..127] of char;
  ReadCount: Integer;
  ReadSize: Integer;
begin
  FirstProcess  := TProcess.Create(nil);
  SecondProcess := TProcess.Create(nil);
 
  FirstProcess.Options     := [poUsePipes]; 
  FirstProcess.Executable  := 'pwd'; 
 
  SecondProcess.Options    := [poUsePipes,poStderrToOutPut];
  SecondProcess.Executable := 'grep'; 
  SecondProcess.Parameters.Add(DirectorySeparator+ ' -'); 
  // this would be the same as "pwd | grep / -"
 
  FirstProcess.Execute;
  SecondProcess.Execute;
 
  while FirstProcess.Running or (FirstProcess.Output.NumBytesAvailable > 0) do
  begin
    if FirstProcess.Output.NumBytesAvailable > 0 then
    begin
      // make sure that we don't read more data than we have allocated
      // in the buffer
      ReadSize := FirstProcess.Output.NumBytesAvailable;
      if ReadSize > SizeOf(Buffer) then
        ReadSize := SizeOf(Buffer);
      // now read the output into the buffer
      ReadCount := FirstProcess.Output.Read(Buffer[0], ReadSize);
      // and write the buffer to the second process
      SecondProcess.Input.Write(Buffer[0], ReadCount);
 
      // if SecondProcess writes much data to it's Output then 
      // we should read that data here to prevent a deadlock
      // see the previous example "Reading Large Output"
    end;
  end;
  // Close the input on the SecondProcess
  // so it finishes processing it's data
  SecondProcess.CloseInput;
 
  // and wait for it to complete
  // be carefull what command you run because it may not exit when
  // it's input is closed and the following line may loop forever
  while SecondProcess.Running do
    Sleep(1);
  // that's it! the rest of the program is just so the example
  // is a little 'useful'
 
  // we will reuse Buffer to output the SecondProcess's
  // output to *this* programs stdout
  WriteLn('Grep output Start:');
  ReadSize := SecondProcess.Output.NumBytesAvailable;
  if ReadSize > SizeOf(Buffer) then
    ReadSize := SizeOf(Buffer);
  if ReadSize > 0 then
  begin
    ReadCount := SecondProcess.Output.Read(Buffer, ReadSize);
    WriteLn(Copy(Buffer,0, ReadCount));
  end
  else
    WriteLn('grep did not find what we searched for. ', SecondProcess.ExitStatus);
  WriteLn('Grep output Finish:');
 
  // free our process objects
  FirstProcess.Free;
  SecondProcess.Free;
end.
That's it. Now you can redirect output from one program to another.

Notes

This example may seem overdone since it's possible to run "complicated" commands using a shell with TProcess like:
Process.Commandline := 'sh -c "pwd | grep / -"';
But our example is more crossplatform since it needs no modification to run on Windows or Linux etc. "sh" may or may not exist on your platform and is generally only available on *nix platforms. Also we have more flexibility in our example since you can read and write from/to the input, output and stderr of each process individually, which could be very advantageous for your project.

Redirecting input and output and running under root

A common problem on Unixes (OSX) and Linux is that you want to execute some program under the root account (or, more generally, another user account). An example would be running the ping command.
If you can use sudo for this, you could adapt the following example adapted from one posted by andyman on the forum ([1]). This sample runs ls on the /root directory, but can of course be adapted.
better way to do this is to use the policykit package, which should be available on all recent Linuxes. See the forum thread for details.
Large parts of this code are similar to the earlier example, but it also shows how to redirect stdout and stderr of the process being called separately to stdout and stderr of our own code.
program rootls;
 
{ Demonstrates using TProcess, redirecting stdout/stderr to our stdout/stderr,
calling sudo on Linux/OSX, and supplying input on stdin}
{$mode objfpc}{$H+}
 
uses
  Classes,
  Math, {for min}
  Process;
 
  procedure RunsLsRoot;
  var
    Proc: TProcess;
    CharBuffer: array [0..511] of char;
    ReadCount: integer;
    ExitCode: integer;
    SudoPassword: string;
  begin
    WriteLn('Please enter the sudo password:');
    Readln(SudoPassword);
    ExitCode := -1; //Start out with failure, let's see later if it works
    Proc := TProcess.Create(nil); //Create a new process
    try
      Proc.Options := [poUsePipes, poStderrToOutPut]; //Use pipes to redirect program stdin,stdout,stderr
      Proc.CommandLine := 'sudo -S ls /root'; //Run ls /root as root using sudo
      // -S causes sudo to read the password from stdin.
      Proc.Execute; //start it. sudo will now probably ask for a password
 
      // write the password to stdin of the sudo program:
      SudoPassword := SudoPassword + LineEnding;
      Proc.Input.Write(SudoPassword[1], Length(SudoPassword));
      SudoPassword := '%*'; //short string, hope this will scramble memory a bit; note: using PChars is more fool-proof
      SudoPassword := ''; // and make the program a bit safer from snooping?!?
 
      // main loop to read output from stdout and stderr of sudo
      while Proc.Running or (Proc.Output.NumBytesAvailable > 0) or
        (Proc.Stderr.NumBytesAvailable > 0) do
      begin
        // read stdout and write to our stdout
        while Proc.Output.NumBytesAvailable > 0 do
        begin
          ReadCount := Min(512, Proc.Output.NumBytesAvailable); //Read up to buffer, not more
          Proc.Output.Read(CharBuffer, ReadCount);
          Write(StdOut, Copy(CharBuffer, 0, ReadCount));
        end;
        // read stderr and write to our stderr
        while Proc.Stderr.NumBytesAvailable > 0 do
        begin
          ReadCount := Min(512, Proc.Stderr.NumBytesAvailable); //Read up to buffer, not more
          Proc.Stderr.Read(CharBuffer, ReadCount);
          Write(StdErr, Copy(CharBuffer, 0, ReadCount));
        end;
      end;
      ExitCode := Proc.ExitStatus;
    finally
      Proc.Free;
      Halt(ExitCode);
    end;
  end;
 
begin
  RunsLsRoot;
end.
Other thoughts: It would no doubt be advisable to see if sudo actually prompts for a password. This can be checked consistently by setting the environment variable SUDO_PROMPT to something we watch for while reading the stdout of TProcess avoiding the problem of the prompt being different for different locales. Setting an environment variable causes the default values to be cleared(inherited from our process) so we have to copy the environment from our program if needed.

Using fdisk with sudo on Linux

The following example shows how to run fdisk on a Linux machine using the sudo command to get root permissions.
program getpartitioninfo;
{Originally contributed by Lazarus forums wjackon153. Please contact him for questions, remarks etc.
Modified from Lazarus snippet to FPC program for ease of understanding/conciseness by BigChimp}
 
Uses
  Classes, SysUtils, FileUtil, Process;
 
var
  hprocess: TProcess;
  sPass: String;
  OutputLines: TStringList;
 
begin  
  sPass := 'yoursudopasswordhere'; // You need to change this to your own sudo password
  OutputLines:=TStringList.Create; //... a try...finally block would be nice to make sure 
  // OutputLines is freed... Same for hProcess.
 
  // The following example will open fdisk in the background and give us partition information
  // Since fdisk requires elevated priviledges we need to 
  // pass our password as a parameter to sudo using the -S
  // option, so it will will wait till our program sends our password to the sudo application
  hProcess := TProcess.Create(nil);
  // On Linux/Unix/OSX, we need specify full path to our executable:
  hProcess.Executable := '/bin/sh';
  // Now we add all the parameters on the command line:
  hprocess.Parameters.Add('-c');
  // Here we pipe the password to the sudo command which then executes fdisk -l: 
  hprocess.Parameters.add('echo ' + sPass  + ' | sudo -S fdisk -l');
  // Run asynchronously (wait for process to exit) and use pipes so we can read the output pipe
  hProcess.Options := hProcess.Options + [poWaitOnExit, poUsePipes];
  // Now run:
  hProcess.Execute;
 
  // hProcess should have now run the external executable (because we use poWaitOnExit).
  // Now you can process the process output (standard output and standard error), eg:
  OutputLines.Add('stdout:');
  OutputLines.LoadFromStream(hprocess.Output);
  OutputLines.Add('stderr:');
  OutputLines.LoadFromStream(hProcess.Stderr);
  // Show output on screen:
  writeln(OutputLines.Text);
 
  // Clean up to avoid memory leaks:
  hProcess.Free;
  OutputLines.Free;
 
  //Below are some examples as you see we can pass illegal characters just as if done from terminal 
  //Even though you have read elsewhere that you can not I assure with this method you can :)
 
  //hprocess.Parameters.Add('ping -c 1 www.google.com');
  //hprocess.Parameters.Add('ifconfig wlan0 | grep ' +  QuotedStr('inet addr:') + ' | cut -d: -f2');
 
  //Using QuotedStr() is not a requirement though it makes for cleaner code;
  //you can use double quote and have the same effect.
 
  //hprocess.Parameters.Add('glxinfo | grep direct');   
 
  // This method can also be used for installing applications from your repository:
 
  //hprocess.Parameters.add('echo ' + sPass  + ' | sudo -S apt-get install -y pkg-name'); 
 
 end.

Parameters which contain spaces (Replacing Shell Quotes)

In the Linux shell it is possible to write quoted arguments like this:
gdb --batch --eval-command="info symbol 0x0000DDDD" myprogram
And GDB will receive 3 arguments (in addition to the first argument which is the full path to the executable):
  1. --batch
  2. --eval-command=info symbol 0x0000DDDD
  3. the full path to myprogram
TProcess can also pass parameters containing spaces, but it uses a different quoting style. Instead of only quoting part of the parameter, quote all of it. Like this:
TProcess.CommandLine := '/usr/bin/gdb --batch "--eval-command=info symbol 0x0000DDDD" /home/me/myprogram';
And also remember to only pass full paths.
See also this discussion about it: http://bugs.freepascal.org/view.php?id=14446

LCLIntf Alternatives

Sometimes, you don't need to explicitly call an external program to get the functionality you need. Instead of opening an application and specifying the document to go with it, just ask the OS to open the document and let it use the default application associated with that file type. Below are some examples.

Open document in default application

In some situations you need to open some document/file using default associated application rather than execute a particular program. This depends on running operating system. Lazarus provides a platform independent procedure OpenDocument which will handle it for you. Your application will continue running without waiting for the document process to close.
uses LCLIntf;
...
OpenDocument('manual.pdf');  
...

Open web page in default web browser

Just pass the URL required, the leading http:// appears to be optional under certain circumstances. Also, passing a filename appears to give the same results as OpenDocument()
uses LCLIntf;
...
OpenURL('www.lazarus.freepascal.org/');
See also:
Or, you could use TProcess like this:
uses Process;
 
procedure OpenWebPage(URL: string);
// Apparently you need to pass your URL inside ", like "www.lazarus.freepascal.org"
var
  Browser, Params: string;
begin
  FindDefaultBrowser(Browser, Params);
  with TProcess.Create(nil) do
  try
    Executable := Browser;
    Params:=Format(Params, [URL]);
    Params:=copy(Params,2,length(Params)-2); // remove "", the new version of TProcess.Parameters does that itself
    Parameters.Add(Params);
    Options := [poNoConsole];
    Execute;
  finally
    Free;
  end;
end;

See also

Friday, December 22, 2017

Napravite aplikaciju koja otvara druge datoteke i aplikacije, a pri tome pamti sve sto ste sa njom otvorili- ovo ne postoji, a bilo bi veoma korisno svakom zaposlenom koji intenzivno koristi kompjuter

https://www.howtogeek.com/107965/how-to-add-any-application-shortcut-to-windows-explorers-context-menu/

Napravite aplikaciju koja otvara druge datoteke, a pri tome pamti sve sto ste sa njom otvorili- ovo ne postoji, a bilo bi veoma korisno svakom zaposlenom koji intenzivno koristi kompjuter.

Zamislite da sve što ste ikada otvorili sa ovom aplikacijom (desni taster miša na neki Word dokument, pa opcija OTVORI, umesto klasične Open na vrhu Context Menija) bude registrovano u SQLite bazi podataka i da u nekom gridu imate spisak svih linkova koje ste otvarali sa datumom otvaranja. Još da dodamo pretragu po imenu i gde bi nam kraj bio.

Eto ideja za Microsoft da ugradi u neki budući Windows ili Google-u da ugradi u neki budući Android.

Šta inače rade njihovi zaposleni programeri, IT menadžeri, developeri, zar nikome ništa slično nije palo na pamet ?

Dobijaju sramno velike plate i bonuse, a ovako nešto korisno nikome da padne na pamet ?

Ovo je gospodo iz Microsofta i Google-a nešto što bi svaki korisnik Vašeg operativnog sistema želeo da ima.

Jedan log fajl u kome bi se registrovali svi linkovi ka pokrenutim datotekama i aplikacijama sa datumima otvaranja i mogućnosti pretrage ove baze ili log fajla. A kada neko klikne na neki od linkova u tom log fajlu da se otvori odgovarajući dokument ponovo.

Ne mogu da verujem da to još nikome nije palo na pamet, nego samo meni !

Pošto je meni prvom palo na pamet, evo ja sam i prvi napravio ovu aplikaciju:

Evo novi freeware za download:

https://goo.gl/zd26LY

Prvo raspakujete arhivu otvarac2----password----raspakuj.zip koristeći password raspakuj.

A zatim prati uputstvo za instalaciju:

USER MANUAL:


1) In Windows Explorer, My Computer or My Documents just  right click mouse on document (readme.rtf or something else), Context Menu will appear

2) Click on option OTVORI in Context Menu





Evo nove verzije mnogo bolje, ako slučajno imate problema sa instalacijom kliknite na mojsetup.exe desnim tasterom miša i u Context Menu-ju odaberite "Run As Administrator", jer aplikacija kreira folder c:\otvarac pa može se desiti da Vam operativni sistem Windows traži da mu dozvolite ovu operaciju.

Naravno, ukoliko imate neki zaštitni program na sistemu dodajte folder i aplikaciju na listu dozvoljenih aplikacija.

Tehnologije koje sam primenio u ovoj mojoj aplikaciji:

Inno Setup Compiler, Mutex in FPC, FPC, Regedit in Inno, Memo box i jedna tekstualna datoteka baza.txt u koju se beleže svi programi i datoteke koje ste otvarali pomoću ove aplikacije (desni taster miša, pa opcija OTVARAC). Veoma jednostavno i veoma efektno, a koliko je korisna aplikacija ne treba ni govoriti. Od sada veoma jednostavno i lako pronalazim Microsoft Office dokumente, čak i ukoliko sam ih dnevno otvarao po hiljadu.



Jer Windows 10 pamti samo poslednjih 30 dokumenata, a zamislite da ste inspektor, advokat, pravnik ili neki javni beležnik koji dnevno ima da otvori i odštampa na stotine i hiljade dokumentata, onda Vam sigurno treba ovaj program !!!

Ukoliko radite u nekoj pravnoj sužbi ili što bi rekli "državni posao" onda imate sreće da ste pronašli ovaj program na internetu ("Kao kec na jedanaest").


Zašto je bitno da u buduće obavezno otvarate datoteke na ovaj način, a ne duplim klikom na levi taster miša ili opcijom Open u Context Menu-ju ?

Jednostavno zato što ćete imati spisak svih otvorenih datoteka ikada, a on je nezamenjiv kod ljudi koji otvaraju veoma velik broj dokumenata i žele da imaju mogućnost evidencije svih pokretanih aplikacija, sa mogućnošću ponovnog startovanja istih - upravo iz ove aplikacije.






U Novom Sadu, 22.12.2017.

Rad i posao u Nemackoj

Šta ste to napravili, kakve su to aplikacije koje nudite ?

Evo srpskog freeware-a:

https://goo.gl/EDC2VU

za preuzimanje (aplikacije rade u svim Windows-ima od XP do 10, jedino ukoliko koristite Windows 7 do 10, onda treba da kliknete na desni taster miša ikonice aplikacije i startujete je kao Administrator - "Run As Administrator"). JanuarPacker je jedinstvena aplikacija koja u sebi sadrži nekoliko veoma korisnih aplikacija. Probajte Web Browser u okviru JanuarPacker aplikacije, sigurno niste videli ništa slično - aplikacija obiluje zvučnim efektima, pa je potrebno da uključite zvučnike.

Za razliku od svih drugih mi ne nudimo priče, nego linkove ka konkretnim besplatnim primerima veoma kvalitetnim i korisnim svim korisnicima računara, kako početnicima, tako i formiranim profesionalcima u IT industriji.

Šta to lepo i korisno nudite svetu preko svog Facebook, Instagram ili Twitter profila ?

Da li ste napravili neku korisnu aplikaciju u skorije vreme i postavili da je besplatno ljudi koriste ?

 ***

Thursday, December 21, 2017

Interesting Codes for Android . sam popravi svoj tablet

http://www.smartmobilephonesolutions.com/content/how-to-fix-the-touch-screen-on-an-android-cell-phone




This page contains a list of codes that can be entered into most Smartphones to retrieve important information run diagnostics and test the functionality of the device.
The codes below are primarily for Smartphones running on the Android Operating System but some codes listed will also work on basic phones and Smartphones that might not be built on the Android OS such as iPhones (iOS), Windows Phones, Nokia Phones (Symbian), etc. Some codes only work for specific manufacturers, some for specific versions of the operating system, some makes and models of phones just don’t like to work at all. 
Disclaimer: This page is for educational and informative purposes only, and a few of these codes I wouldn’t recommend a basic or novice phone user to perform. Some of these codes can clear important information from your device if not already saved properly. So all in all, read the description of what the code is intended to do and perform these codes at your own risk because I will not be held responsible or accountable. Otherwise enjoy the codes and enjoy the article.
To input these codes on your phone all you have to do is open up your dialer as though you’re dialing a telephone number and then enter the code. After typing in the code the phone should pull up whatever option you’re testing. Some of these codes you might need to enter the code and then call/dial it.
*#*#4636#*#* or *#*#INFO#*#* can be used to check a lot of things on most Android Smartphones. Including:
Phone information -allows you to run a ping test, and shows a ton of interesting information about the phone.
Battery Information – now you can remove that power app you installed on your phone, all the common information you need about your battery and charging is here.
  • Battery Status: Shows whether the device is charging or if the battery is full.
  • Power Plug: Shows how the device is charging, AC (wall charger), USB (computer) etc.
  • Battery level: at what Percent the battery is charged.
  • Battery scale: should read “100”.
  • Battery Health: should say “Good”. If it shows “unknown” or “unknown error” then you should power cycle (turn the phone off than on) and check again. If it still doesn’t say good. Then the battery itself is likely defective.
  • Battery Voltage: really isn’t something the average phone user is going to need to worry about.
  • Battery Temperature: if your phones getting HOT you can check and see if it’s your battery that’s heating up or the phone itself.
  • Battery technology: usually just shows Li ion (because of the common Lithium Ion batteries found in the majority of these devices).
  • Time since boot: shows the amount of time since you last booted up or turned on the phone.
Battery History
Usage Statistics – shows the apps and programs that have been running on the device and can show how often they’re being opened and used.
*#7353# will access the Device Diagnostic Tool on Samsung phones and some other Smartphones excluding the HTC.
*#*#3424#*#* is how to open the Device Diagnostic Tool on an HTC Android phone.
*#06# shows the IMEI number of your phone. The IMEI is a unique 15 digit number for your specific phone, basically the Social Security number of your phone. Sometimes when typing in *#06# it will add an additional 2 digits at the end. The first 15 digits shown before any space or dash is your IMEI.
*2767*3855# is a code to perform a VERY THOROUGH complete wipe on a Samsung phone. Never type in this code until you backup your entire phone, it will not erase your Operating System or preinstalled applications. It will erase all personal data and settings. If you have tried to perform a Factory Data Reset on your Smartphone and it didn’t solve your issue then this code might be exactly what you’re looking for. PS also remove your SD card or Memory card from the phone before using this code.
*983*57# can be used to Factory Data Reset some Android devices, ZTE phones especially.
*#0*# will pull up the Device Diagnostic Tool on a Motorola Atrix that’s still using the Android 2.1 OS (Operating System).
#3282 or #DATA should show the data usage for Verizon phones.
*4 then hit 4 again to get to the menu for Sprint Customers.
 *3282# or *DATA# to check data usage on AT&T phones.
*646# or *MIN# to check minutes on an AT&T cell phone.
#646 or #MIN Checks the current month's unbilled airtime usage on Verizon phones.
*225# Shows Bill Balance on AT&T mobile phones.
*729# accesses a Bill Pay option on AT&T Phones.
*639# can be used to check upgrade eligibility on an AT&T phone.
*#*#7780#*#* is an alternate code to perform a Factory Data reset on some Android Smartphones. Don’t do this unless you’ve backed up your phone so you don’t lose anything. Once you type in this code the phone will show the option to erase the memory on the device and provide the option to format the SD card as well. Note: In order to finish the reset you will have to tap the “Reset phone” button shown on the screen.
*#7380# is a soft reset code to restore the phones original factory default settings (just settings not a full clear) on Nokia mobile phones.
*#7370# is a hard reset on Nokia phones, this restores the whole phone, not just the settings, so make sure you do a backup first, if possible.
*#*#34971539#*#* this code can be used to get information about your phone’s camera. It shows following:
Update camera firmware in image (Don't try this option because it will most likely break your phone)
Get firmware update count
Get camera firmware version
Update camera firmware in SD card
*#1234# displays software/firmware information.
*#*#7594#*#* this code can be used to change the "End Call/Power" option on your phone. So instead of having to select the Silent mode, Air Plane mode or Power off, you can just use the power key to power the phone right off.
*#*#232339#*#* or *#*#526#*#* or *#*#528#*#* - Wireless LAN (WLAN) test. Just use the phones "Menu" button to start the various tests).

*#*#232338#*#* Shows the Wireless LAN (WLAN) MAC address WiFi and can show “power save mode Settings”.
*#*#273283*255*663282*#*#* will open a file manager of sorts where you can backup your media files such as Images, M3 (Sound), Video and Voice memos.

*#*#197328640#*#* opens a Service Mode where you can run various tests such as debugging the screen, gather version information etc.
*#*#1472365#*#* or *#*#1575#*#* will allow you to access a GPS test.
*#*#232331#*#* pulls up a Bluetooth test screen.
*#*#232337#*# Shows the Bluetooth Device Address.
*#*#7378423#*#* or *#*#SERVICE#*#* Sony Battery Health test
*#*#4986*2650468#*#* - PDA, Phone, H/W, RFCallDate.
*#*#1234#*#* - PDA and Phone.
*#*#44336#*#* - PDA, Phone, CSC, Build Time, Changelist number.
*#*#3264#*#* pulls up the RAM version.
*#*#2222#*#* shows the FTA HW Version.
*#*#1111#*#* shows the FTA SW Version.
##21# will cancel your phones registration from your service provider and should allow you to connect to the closest tower in your area. Once you type in the code you will have to actually call it, it will show a message and then go through… try and make a call or two and see if the service has improved. If yes enjoy, if not then power cycle your phone (turn it off and then back on). I don’t usually recommend this code be used unless you’re having pretty constant network related issues. If for some reason you have minimal service after entering this code and you have tried restarting your phone then you might have to contact your wireless provider to get them to reconnect you to the network (which power cycling should do for you), just call in and let them know that you suddenly had no service, should be one of the standard things they check for service related issues, just have them send an OTA (Over The Air Activation) to your phone (so far only confirmed on AT&T phones).
*#*#0283#*#* can check the Packet Loopback for networking.
*#*#0*#*#* - run a LCD test on your screen.
*#*#0673#*#* OR *#*#0289#*#* is how you run a Melody test for checking the sound. I believe this one is for the external speaker (the speaker that plays music on the phone).
*#*#0842#*#* Device test (vibration test and back light test).
*#*#2664#*#* Touch Screen test for if you think you might have dead spots or areas that don’t respond on the screen.
*#*#2663#*#* to show the Touch Screen version.
*#*#0588#*#* is a Proximity Sensor Test. The proximity sensor is a small little sensor, usually on the top of the phone next the logo or speaker you hold up to your ear, and its purpose is to know when you put your phone to your ear, so that the phone will lock, and you won’t accidently press keys when talking to other people. It then is supposed to realize when you’re removing your phone from your ear so that it can show the display again. If your phone is remaining on a black screen and you’re having issues ending calls then it could be your proximity sensor.
*3001#12345#* opens a Field Test on iPhones. You’ll have to press dial/call for this code to go through. This code opens a lot of different options to go through and see how well or efficiently your iPhone is working. One such future shown includes your phones signal. After typing this code into the phone the signal bars actually turn into a number. The lower the number the worse your signal strength is. Remember the number is a negative so -90 is a worse signal strength on your phone than a -80. Using this code can access a ton of technical information on an iphone, once done going through what you want then just press your home key to exit the Field Test.
*777# then call/dial, should open the account balance on a prepaid iPhone.
*#61# can be used to check the number for unanswered calls on iPhone. Use the code *#62# if you don’t have any service currently available. *#67# if the iPhone is busy.
*#21# provides information on call forwarding options.
*#119# or #*119# is supposed to help take a phone out of Emergency Mode. (submitted by a Sprint employee)
*#30# should show whether the phone has the setting to display its caller ID field enabled or disabled (I have yet to confirm this code. I think it is primarily for iPhones). *#76# is a similar code.
*#33# can be used to check for call control bars on an iPhone.
*#43# shows whether call waiting is enabled or disabled on iPhone.
I hope you enjoyed the article and saw some interesting codes that you can use on your phone. If you didn’t see any that you know of and have tried and confirmed yourself then let me know in the comments below. Don’t forget to include the Star Code and what the code actually does in the comment.
I look forword to hearing what you have to say. And don’t forget to check the site for other fun and interesting articles. Enjoy and I look forward to hearing from you.

Problemi sa tablet androidom


Make sure that your hands are clean and dry, then try these steps:
  • If you have a case or screen protector on your device, try removing it.
  • Clean the screen with a soft, slightly damp, lint-free cloth.
  • Unplug your device.
  • Restart your device. If you can't restart it, you can force restart your device.
Or other method
1 Restart Android Device
Before rushing into any other troubleshooting procedure, restart your Android phone or tablet to fix software glitches that may prevent the screen from functioning. To restart android device with touch screen not working:
  • Press and hold the power button until the screen becomes black;
  • After 1 minute or so, hold the power button again to power on the device.
In many cases, the touch screen will respond normally after the device reboots.
2. Remove Memory Card & SIM Card
Sometimes, faulty memory card or SIM card should take the blame. Therefore,
Power off your device (keep holding power button if the screen is totally unresponsive);
Remove back cover of your Android device and take off memory & SIM card;
Reboot the device and see if the problem is gone.
3. Put Device in Safe Mode
Corrupted or troublesome third-party apps could also cause touch screen problem on Android phone or tablet. Under the safe mode, all third-party apps that you download will be disabled. So if the touch screen works well in safe mode, then you should uninstall some of the third-party apps, especially those that were installed recently before the touch screen problem starts.
  • Power off your Android device;
  • Long press power button to reboot the device;
  • When you see the Samsung, Nexus, LG or other brand logo, release power button and hold down Volume Down button;
  • Release Volume Down button when the device boots up with a Safe mode indicator on the bottom left corner.
If your touch screen just lags or respond incorrectly, you can also try to enter safe mode in this method:
  • Hold power button until the power options menu appears;
  • Long-press the Power Off
  • When you see the message whether to reboot your device into safe mode, tap "OK".
4. Factory Reset Android Device in Recovery Mode
If the touch screen is completely unresponsive, factory resetting the device in Recovery Mode may help. However, this will delete all data in your Android device, including downloaded apps, photos, messages, contacts, etc. Therefore, use this as the last resort and if possible, have a backup to your Google account beforehand.
5. Calibrate Touch Screen on Android with Apps
There are apps in Google Play Store that can calibrate your phone/tablet touch screen and improve its accuracy and responsiveness. These apps are especially helpful if your touch screen respond too slow or inaccurately. Type "touch screen calibration" on the search bar in Play Store and you should get quite a few results. Read the reviews carefully before download.