Posts: 1,769
Threads: 410
Joined: Feb 2003
Is it possible to pass these parameters in an exe and roll them into 3 vars?
foobar.exe "c:\foo bar\test.txt" "foobar foo" "bar-foo bar"
var0=c:\foo bar\test.txt
var1=foobar foo
var2=bar-foo bar
Posts: 12,135
Threads: 142
Joined: Dec 2002
If you run the exe from QM:
Function Function131
;/exe
function str'a b
mes _s.format("''%s'', %i" a b)
Macro
mac "Function131" "" "x" 5
If not from QM, use tok. Or probably can be used an undocumented command line syntax that QM uses to pass arguments to exe like in the above code.
Posts: 12,135
Threads: 142
Joined: Dec 2002
Example with setstruct/getstruct.
This is better to use when you run the exe from qm but cannot use mac.
Function Function132
;/exe
type ZUU str'a b
ZUU z
_s=_command
_s.setstruct(z); err mes- "incorrect command line"
mes _s.format("''%s'', %i" z.a z.b)
Macro
type ZUU str'a b
ZUU z
z.a="x"
z.b=8
run "$myqm$\function132" _s.getstruct(z)
----------------
When not from QM.
Function Function133
;/exe
type ZU str'Aa b double'c str'd
ZU z
_s=_command
_s.setstruct(z 3); err mes- "incorrect command line"
mes _s.format("''%s'', %f, ''%s''" z.Aa z.c z.d)
Macro
str s=
;aa xxx
;c 10.95
;d "line1[]line2"
run "$myqm$\function133" s
Posts: 25
Threads: 4
Joined: Oct 2010
This macro statement
mes _command
get me the whole argument passed to the compiled macro.exe file.
I call it using "macro.exe" Hi its me
output
Hi its me, over here.
But if I need need to separate the passed commandline parameter into 2 or 3 or more arguments,
Example
macro.exe "Hi" "its me," "over here."
I need those 2 or 3 arguments for different purposes or when no arguments are passed, can someone show how its done in QM compiled macro.exe? I' m still trying to figure out how QM works(yeah I'm a newbie here:? ). Thanks
Posts: 12,135
Threads: 142
Joined: Dec 2002
Function ParseCommandLine
;/
function $cmdLine ARRAY(str)&a
;Parses command line.
;Uses the same rules as most programs. <link "http://www.google.com/search?q=site%3amicrosoft.com%20Parsing%20C%2b%2b%20Command-Line%20Arguments">Read more</link>.
;cmdLine - command line.
;;;Can be path followed by command line. Then a[0] will be the path.
;a - receives command line arguments.
a=0
if(empty(cmdLine)) ret
int i n
word** w=CommandLineToArgvW(@cmdLine &n)
for(i 0 n) a[].ansi(w[i])
LocalFree w
example
Macro Macro1465
out
str cl="/A /B bbb /c ''ccc ccc'' ''\''ddd ddd\''''"
;str cl="''c:\xx xx\yyy.exe'' /A /B"
ARRAY(str) a
ParseCommandLine(cl a)
int i
for i 0 a.len
,out a[i]
Posts: 25
Threads: 4
Joined: Oct 2010
With macro1
---------
out
str cl="This is a test my cute yes."
;str cl="''c:\xx xx\yyy.exe'' /A /B"
ARRAY(str) a
ParseCommandLine(cl a)
int i
for i 0 a.len
,out a[i]
----------
I get this output
This
is
a
test
my
cute
yes.
But with this macro2
out
str cl="This is a "test my" cute yes."
;str cl="''c:\xx xx\yyy.exe'' /A /B"
ARRAY(str) a
ParseCommandLine(cl a)
int i
for i 0 a.len
,out a[i]
I get this error output instead
Error in Testparamter with quote: missing ( after function name, or ; after statement.
Is it possible to get this output below with the above macro2 code? :?:
This
is
a
test my
cute
yes.
I'm trying to get the same parameter commands just like using a batch file or vbscript.
If possible I also would like to counter for the number of arguments passed and also error to cater if no arguments passed.
Thanks.
Posts: 12,135
Threads: 142
Joined: Dec 2002
Macro Macro1497
str cl="This is a ''test my'' cute yes."
;or
str cl2=
;This is a "test my" cute yes.
Macro Macro1501
ARRAY(str) a
ParseCommandLine(cl a)
;a.len is number of arguments
if a.len=0
,mes "error"
,ret -1 ;;an exit code
Posts: 5
Threads: 0
Joined: May 2014
Hello community.
I am totally new to QM and I have a question please:
How to use such macro function code from above post as a program function?
I don't get it. Even the help file didn't help me.
My example code would look like this:
test-commandline
;/exe
Function ParseCommandLine
/
function $cmdLine ARRAY(str)&a
a=0
if(empty(cmdLine)) ret
int i n
word** w=CommandLineToArgvW(@cmdLine &n)
for(i 0 n) a[].ansi(w[i])
LocalFree w
ARRAY(str) a
ParseCommandLine(cl a)
int i
for i 0 a.len
mes a[i]
test-commandline2
run "$my qm$\test-commandline.exe" "/a /b /c"
- - -
EDIT
I read now quickmacros.com/forum/viewtopic.php?p=3524
2. In QM, create new function. To create new function, click menu File -> New -> New Function.
Question:
Do I really have to do this and utilize a second "document"?
Can't I just copy that function together with my code?
Now, if I will use "File -> New -> New Function", and if I compile to exe, would every needed functions be collect automatically and pack to the exe too?
Thanks
Posts: 12,135
Threads: 142
Joined: Dec 2002
Yes need a second "document". These documents are not separate files.
In the newest QM beta also can be used sub-functions. Multiple private functions can be in single document.
QM now has function ExeParseCommandLine. Don't need this forum function.
Quote:Now, if I will use "File -> New -> New Function", and if I compile to exe, would every needed functions be collect automatically and pack to the exe too?
Yes.
Posts: 5
Threads: 0
Joined: May 2014
Thanks.
Of course, after posting I get how it works:
Function "document": ParseCommandLine
/
function $cmdLine ARRAY(str)&a
a=0
if(empty(cmdLine)) ret
int i n
word** w=CommandLineToArgvW(@cmdLine &n)
for(i 0 n) a[].ansi(w[i])
Macro-1: (my program code, utilizing the above function. And "_command" will get me access to the command line parameters)
;/exe
ARRAY(str) a
ParseCommandLine(_command a)
int i
for i 0 a.len
mes a[i]
Macro-2: (my example program to try out Macro-1)
run "$my qm$\Macro-1.exe" "/a /b /c"
Many thanks.
Now I understand a little bit more :mrgreen:
Now I go trying your other suggestions.
Posts: 12,135
Threads: 142
Joined: Dec 2002
with sub-function would be
Macro Macro2277
str cl="a b c"
ARRAY(str) a
sub.ParseCommandLine(cl a)
int i
for(i 0 a.len) out a[i]
#sub ParseCommandLine
function $cmdLine ARRAY(str)&a
;Parses command line.
;Uses the same rules as most programs. <link "http://www.google.com/search?q=site%3amicrosoft.com%20Parsing%20C%2b%2b%20Command-Line%20Arguments">Read more</link>.
;cmdLine - command line.
;;;Can be path followed by command line. Then a[0] will be the path.
;a - receives command line arguments.
a=0
if(empty(cmdLine)) ret
int i n
word** w=CommandLineToArgvW(@cmdLine &n)
for(i 0 n) a[].ansi(w[i])
LocalFree w
Posts: 135
Threads: 33
Joined: Aug 2009
Hi Gintaras and all QM fellows!
Two questions, please:
1- Why the delay exe vs function?
2- How to pass parameters from a QM exe to a QM function?
Regards.
Macro Macro412
out
long t1 t2 t3
t1=perf
run "$my qm$\Macro414.exe" "a b c"
t2=perf
Function18 "a b c"
t3=perf
out F"{(t2-t1)} microsec"
out F"{(t3-t2)} microsec"
out F"{(t2-t1)/(t3-t2)} times faster"
;148068 microsec
;47 microsec
;3150 times faster
Function Function18
function str's
ARRAY(str) a
tok(s a)
int i
for i 0 a.len
,out a[i]
Macro Macro414 <- This is my exe
ARRAY(str) a
ExeParseCommandLine(_command a)
int i
for i 0 a.len
,out a[i]
;BEGIN PROJECT
;main_function Macro414
;exe_file $my qm$\Macro414.exe
;icon <default>
;manifest $qm$\default.exe.manifest
;flags 6
;guid {57C55193-8C16-4D76-A298-F6D3488E66DE}
;END PROJECT
Posts: 12,135
Threads: 142
Joined: Dec 2002
1. run depends on spe. Before insert spe 0.
2. To pass some data from exe to a function running in QM, not in that exe? Is that function running then (waiting for exe data), or it should be called when exe wants to pass data?
Posts: 135
Threads: 33
Joined: Aug 2009
Thanks for your help.
Gintaras Wrote:1. run depends on spe. Before insert spe 0. It runs faster, but still 500 times slower than QM function
Gintaras Wrote:2. To pass some data from exe to a function running in QM, not in that exe? Is that function running then (waiting for exe data), or it should be called when exe wants to pass data? Yes, the QM func runs a QM exe and that exe returns some data to the first QM func waiting for those results.
In another post, you explained how to do the same with DLLs. It was amazing as we can combine easy development with QM and the power of c++. I would like to do something like this with a QM exe.
Regards.
Posts: 12,135
Threads: 142
Joined: Dec 2002
1. run can be replaced with CreateProcess, it is the fastest function to start a process, but probably will be not much faster. Also try run flag 0x30000. Or QM function StartProcess with first argument 0, it simply calls CreateProcess.
2.1. Does exe return data when it exits? Or it continues running after returning data? Should the QM function wait until exe exits?
2.2. What is data size?
2.3. Exe can store data in a file, or in registry, or in shared memory, etc. Then need a way to notify the QM function and synchronize data access. It depends on 2.1.
Posts: 135
Threads: 33
Joined: Aug 2009
1. ok. Thanks, I will try these options.
2.1. Yes, exe returns data and stops. And yes, QM func waits until exe exits.
2.2. Some integers will be ok.
2.3. The faster way would be the best.
Posts: 12,135
Threads: 142
Joined: Dec 2002
If need just to return a single integer:
Function this_is_my_exe
;...
ret 5 ;;return an integer
;BEGIN PROJECT
;main_function this_is_my_exe
;exe_file $my qm$\this_is_my_exe.exe
;icon <default>
;manifest $qm$\default.exe.manifest
;flags 6
;guid {D3960F15-7393-4411-8A6A-0731CBBF8E01}
;END PROJECT
Macro Macro2473
int ec=CreateProcessSimple("''$my qm$\this_is_my_exe.exe'' /a ''b''" 1)
out ec
Function CreateProcessSimple
;/
function# $cl [flags] ;;flags: 1 wait until exits
;Calls CreateProcess.
;Returns 0. If flag 1, returns the exit code.
;Error if fails.
;cl - program path, optionally followed by command line arguments.
;;;Program path can be enclosed in quotes. Should be enclosed if contains spaces.
;flags:
;;;1 - wait until exits and return the exit code.
;NOTES
;CreateProcess fails if would show UAC consent. Use run() instead.
;EXAMPLE
;int ec=CreateProcessSimple("''$my qm$\this_is_my_exe.exe'' /a ''b''" 1)
;out ec
opt noerrorshere 1
sel cl 2
,case ["$*","%*"] cl=_s.expandpath(cl)
,case ["''$*","''%*"] _s.expandpath(cl+1); _s-"''"; cl=_s
STARTUPINFOW si.cb=sizeof(si)
PROCESS_INFORMATION pi
if(!CreateProcessW(0 @cl 0 0 0 0 0 0 &si &pi)) end _s.dllerror
CloseHandle pi.hThread
if flags&1
,opt waitmsg -1
,wait 0 H pi.hProcess
,int R
,GetExitCodeProcess pi.hProcess &R
CloseHandle pi.hProcess
ret R
Posts: 12,135
Threads: 142
Joined: Dec 2002
Another way - create console exe, and run it with RunConsole2.
Function this_is_my_console_exe
ExeConsoleWrite "some text"
;BEGIN PROJECT
;main_function this_is_my_console_exe
;exe_file $my qm$\this_is_my_console_exe.exe
;icon <default>
;manifest $qm$\default.exe.manifest
;flags 70
;guid {D3960F15-7393-4411-8A6A-0731CBBF8E01}
;END PROJECT
Macro Macro2473
str progPath.expandpath("$my qm$\this_is_my_console_exe.exe")
str s
RunConsole2 F"''{progPath}'' /a ''b''" s
out s
Posts: 135
Threads: 33
Joined: Aug 2009
Thanks for your help.
Best regards.
Posts: 1,058
Threads: 367
Joined: Oct 2007
Dear Gintaras,
I would appreciate it if you could advise on the modifications (if possible) in CreateProcessSimple so that this_is_my_exe returns a string value. I have tested it and it works with RunConsole2 but I would prefer CreateProcessSimple, if feasible.
Best regards.
Posts: 12,135
Threads: 142
Joined: Dec 2002
Let this_is_my_exe write the string in registry.
When CreateProcessSimple returns a success code, get the string from registry.
Posts: 1,058
Threads: 367
Joined: Oct 2007
Many thanks. Actually, this is what I did using a Qm registry (.ini) file.
Posts: 1,058
Threads: 367
Joined: Oct 2007
I want to use a file's right context menu entry to invoke, using this file, a qm .exe file, namely :
Registry entry : "C:\Documents and Settings\SES\My QM\Exe\GoToAFJ_Exe.exe" "%1"
I envisage a difficulty in obtaining the file's path (%1 above) in macro GoToAFJ_Exe. Any advice is welcome.
Posts: 1,058
Threads: 367
Joined: Oct 2007
OK, solution found using Macro414 above. ExeParseCommandLine proved to be very useful.
|