passing command line params during run-time

I am trying to pass command line parameters sent to an app to an existing instance of the same application. I thought there might be a way to do this with sendmessage() but i have been unsuccessful.

Any suggestions?
LVL 1
rdobsonAsked:
Who is Participating?
 
d003303Connect With a Mentor Commented:
Hi rdobson,
sorry, no suggestion, but a working answer ;-)
It works like I described above. The memory mapped file code is, like I said, from JB or Zif. I just modified it for your needs.
Here we go:

// memory mapped file helper unit
unit mmtrans;

interface

uses Windows, Messages;

const
  WM_CommandLineMessage = WM_USER + 1;

function GetFirstInstance: THandle;
function GetCmdParamsFromInstance: string;

implementation

uses SysUtils, Forms;

const
  // I used a GUID to ensure a unique MM filename
  MMUniqueFileName = '{0C8CF160-0C3F-11d2-B4F4-0000E82D8A65}';
  // maximim size of the MM file
  MMFileSize       = 1024;

var
  // handle to the MM file
  MMFileHandle : THandle;
  // memory pointer to the MM file view
  MMFileView   : PChar;

function GetFirstInstance: THandle;
var PrevInstHandle : ^THandle;
begin
  PrevInstHandle := Pointer(MMFileView);
  Result := PrevInstHandle^;
  if PrevInstHandle^ = 0
   // we are the first instance
   then PrevInstHandle^ := Application.Handle
   // we are the second instance, copy command line parameters
   else StrCopy(@MMFileView[4], GetCommandLine);
end;

function GetCmdParamsFromInstance: string;
begin
  // called if we are the first instance
  Result := string(PChar(@MMFileView[4]));
end;

procedure MapFile;
begin
  // open MM file
  MMFileHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, MMFileSize, PChar(MMUniqueFileName));
  // map view to MM file
  MMFileView := MapViewOfFile(MMFileHandle, FILE_MAP_WRITE, 0, 0, MMFileSize);
end;

procedure UnMapFile;
begin
  // unmap opened view to MM file
  if (MMFileView <> nil)
   then UnmapViewOfFile(MMFileView);
  // close MM file
  if MMFileHandle <> 0
   then CloseHandle(MMFileHandle);
end;

initialization
  MapFile;

finalization
  UnMapFile;

end.

// project file
program instchk;

uses
  Windows,
  Forms,
  _instchk in '_instchk.pas' {Form1},
  mmtrans in 'mmtrans.pas';

{$R *.RES}

function CheckInstance: Boolean;
var PrevInstHandle : THandle;
begin
  PrevInstHandle := GetFirstInstance;
  Result := (PrevInstHandle <> 0);
  if Result
   then PostMessage(PrevInstHandle, WM_CommandLineMessage, 0, 0);
end;

begin
  if CheckInstance
   then Halt(0);
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

// form unit
unit _instchk;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, mmtrans;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure ProcessCommandLine(CmdLine : string);
    procedure FilterCommandLineMessage(var Msg: TMsg; var Handled: Boolean);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ProcessCommandLine(CmdLine : string);
begin
  MessageDlg(CmdLine, mtInformation, [mbOk], 0);
end;

procedure TForm1.FilterCommandLineMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if Msg.message = WM_CommandLineMessage then
   begin
     Handled := true;
     ProcessCommandLine(GetCmdParamsFromInstance + ' - from second instance');
   end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := FilterCommandLineMessage;
  ProcessCommandLine(string(GetCommandLine) + ' - from first instance');
end;

end.

Have fun,
Slash/d003303
0
 
lobracoCommented:
Well, I think that you should take a dump on your project that should be programed in VB. Thank you!
0
 
rdobsonAuthor Commented:
no comments from vb lovers.... thank you!
0
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

 
Edo082297Commented:
Hi rdobson
  There are a number of ways to accomplish this. Some are more appropriate than others, depending on what you are doing. Could you be a bit more specific?

Edo
0
 
ZifNabCommented:
Hi, rdobson, like Edo, can you be a bit more specific? Thanks. Zif.
0
 
MatveyCommented:
Maybe you mean to execute another app from yours with command line parameters???
(wild quess)
-Use some component for that if so...
0
 
altenaCommented:
Sometimes one gets real mind boggling stuff here...

WHY would you ever want to do this?... (it could be me)

IMHO the command line parameters are used once: when the
instance starts. thats it. What are you trying to do?

There are other ways to pass data from one app to another.

0
 
rdobsonAuthor Commented:
I am running a powerpoint application from a delphi app and i want to be able to have some slides have actions that send them back to the application to get dynamic information. The way I have it set up now is to close the application when they leave a form and then relaunch when it is called from powerpoint with command line params to determine when information should be shown.

I would like to just leave the application running and launch powerpoint and then when powerpoint trys to run my application again, I can just send the existing instance of the app the command line params so that it can display the correct information.

I hope this does a better job of explaining. Thanks!
0
 
d003303Commented:
OK,
so the best would be to re-launch your app with parameters. It then checks for a previous instance of itself. If a previous instanve exists, it sends the command-line parameters over and closes. So, how to do it ?
The previous-instance-check was answered several times in this forum, you have to use mutexes for that. Take a look in the PAQ area for the answer.
To transfer the parameters in the process space of the previous instance, you should use a memory mapped file to write them in, then send a message to that instance and close. JimBob of ZifNab (don't remember exactly...) have provided an example of the usage of memory mapped files.

So, guys, your turn if you agree to my suggestion to get it work.

Slash/d003303
0
 
altenaCommented:
AHA..so that is what you want. You should have said so
in the first place....

The answer to that question is to use Automation.

My "Delphi" is a bit rusty on this, but basically what you do is
call something like "getobject" (excuse me my VB-syntax, I do all
my Automation from there) That gets you a PowerPoint Aplication object. From there you can drive Powerpoint anywhere you want.

And Remember: Even if you get your command line to work, chances are that the app will break whenever Powerpoint is updated.

Good Luck.
0
 
rdobsonAuthor Commented:
I don't want to get the power point object because I still want my app to be seperate from it. I tried to find information on memory mapped files, but no luck... any suggestions d003303?

0
 
ZifNabCommented:
hi rdobsoon,

Believe that memmory mapped file code is from JB. I'm not that good :-(. Ok, want some more about this? For easy programming mapped files, look at this URL:

sdiclub.softinfo.qss.ru --> go to the system components.

c.u. Zif.
0
 
rdobsonAuthor Commented:
Thanks... that worked great!!!!!!!!!!
0
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.