Home
Top.Mail.Ru Yandeks.Metrika
Forum: "Beginners";
Current archive: 2017.01.15;
Download: [xml.tar.bz2];

Down

Newly rewritten Please rate the "clumsiness of the code" v2 Find similar branches


AlexeyTG   (2014-12-19 20:25) [0]

I did not stupidly copy code pieces, etc. like yesterday when I quickly wanted to do it in a snap. He read, re-wrote the code. Pleasetake a look at how "normal" he is at the moment

program Project1; uses Vcl.Forms, Winapi.Windows, System.SysUtils; Var StartInf: TStartupInfo; ProcInf: TProcessInformation; CmdLine: String; {$ R * .res} function RunApp (const ProgName, ProgParams: String): boolean; begin ZeroMemory (@ StartInf, sizeof (StartInf)); StartInf.cb: = SizeOf (StartInf); CmdLine: = Format (""% s "% s", [ProgName, ProgParams]); Result: = CreateProcess (PChar (ProgName), Pchar (CmdLine), nil, nil, False, NORMAL_PRIORI TY_CLASS, nil, nil, StartInf, ProcInf); end; begin If RunApp ("C: \ Windows \ System32 \ cmd.exe", "/?") Then begin CloseHandle (ProcInf.hThread); WaitForSingleObject (ProcInf.hProcess, INFINITE); CloseHandle (ProcInf.hProcess); RunApp ("C: \ Windows \ System32 \ notepad.exe", "D: \ 1.txt"); CloseHandle (ProcInf.hThread); CloseHandle (ProcInf.hProcess); Application.Terminate; end; end.



кгшзх ©   (2014-12-19 20:34) [1]

remove global variables
and make them parameters.



Rouse_ ©   (2014-12-19 20:48) [2]

1. The first parameter passed to CreateProcess is redundant.
2. All this will not work on executables from InstallShield setupers, ie You will wait only for the completion of the executable, and not for the code that it will run further for execution.
3. If the file that you want to run is not found, then CloseHandle will generate an error under the debugger (regular behavior on an invalid handle during debugging).
4. As I understand it, Pushkin will analyze return codes?



AlexeyTG   (2014-12-19 20:55) [3]

1. On the first parameter I read here http://www.gunsmoker.ru/2009/07/createprocess.html
Application: = "C: \ Program Files \ MySoft \ MyApp.exe"; Params: = "-n: 6 / p5" C: \ Program Files \ MySoft \ Data.bin ""; CmdLine: = Format (""% s "% s", [Application, Params]); CreateProcess (PChar (Application), PChar (CmdLine), ...); So there will never be errors (pay attention to the placement of quotation marks and spaces). And if you do not specify it, your program can have serious security problems. Especially if you do not use quotation marks.
And on another resource where they discussed.

2. the executable is not a setuper, a simple application, the launcher is written for it, it seems to work fine on it.

3, 4 begin
If RunApp ("C: \ Windows \ System32 \ cmd.exe", "/?") Then begin CloseHandle (ProcInf.hThread); WaitForSingleObject (ProcInf.hProcess, INFINITE); CloseHandle (ProcInf.hProcess); RunApp ("C: \ Windows \ System32 \ notepad.exe", "D: \ 1.txt"); CloseHandle (ProcInf.hThread); CloseHandle (ProcInf.hProcess); Application.Terminate; end else Application.Terminate
will it be so normal? :)



AlexeyTG   (2014-12-19 20:57) [4]

kgshzh here you put me into a dead end, if you do their parameters, then what values ​​should be passed to them when the function is called.



Rouse_ ©   (2014-12-19 21:04) [5]


> So there will never be errors (pay attention to the arrangement
> quotation marks and spaces). And if you do not specify it, your
> Programs can have serious security issues.
> Especially if you do not use quotation marks.

Enclose the path to the software in quotation marks, it is written about this both in MSDN and with the article cited by you.


> it will be so normal? :)

Of course not :)
Anyway, remove Application.Terminate - why do you need it here?



Rouse_ ©   (2014-12-19 21:11) [6]

Catch the three launch options, smoke over them:

// Normal start of the process and waiting for its completion function ExecAndWait (const ExeName, Params: string; out ExitCode: Cardinal; Timeout: Cardinal = MaxInt): boolean; var sui: TStartupInfo; pi: TProcessInformation; begin ZeroMemory (@sui, SizeOf (sui)); sui.cb: = SizeOf (sui); Win32Check (CreateProcess (nil, PChar ("" "+ ExeName +" "" + Params), nil, nil, False, 0, nil, nil, sui, pi)); try CloseHandle (pi.hThread); Result: = WaitForSingleObject (pi.hProcess, Timeout) = WAIT_OBJECT_0; if Result and (@ExitCode <> nil) then Win32Check (GetExitCodeProcess (pi.hProcess, ExitCode)); finally CloseHandle (pi.hProcess); end; end; // Start and wait with support for processes with admin manifest function ExecAndWaitElevate (const ExeName, Params: string; out ExitCode: Cardinal; Timeout: Cardinal = MaxInt): boolean; var SEI: TShellExecuteInfo; begin ZeroMemory (@SEI, SizeOf (TShellExecuteInfo)); SEI.cbSize: = SizeOf (TShellExecuteInfo); SEI.lpFile: = PChar (ExeName); SEI.lpParameters: = PChar (Params); SEI.fMask: = SEE_MASK_NOCLOSEPROCESS; SEI.nShow: = SW_SHOWNORMAL; Win32Check (ShellExecuteEx (@SEI)); try Result: = WaitForSingleObject (SEI.hProcess, Timeout) = WAIT_OBJECT_0; if Result and (@ExitCode <> nil) then Win32Check (GetExitCodeProcess (SEI.hProcess, ExitCode)); finally CloseHandle (SEI.hProcess); end; end; // Start the process with raising rights to the admin function ExecAndWaitElevate2 (const ExeName, Params: string; out ExitCode: Cardinal; Timeout: Cardinal = MaxInt): boolean; var SEI: TShellExecuteInfo; begin ZeroMemory (@SEI, SizeOf (TShellExecuteInfo)); SEI.cbSize: = SizeOf (TShellExecuteInfo); SEI.lpFile: = PChar (ExeName); SEI.lpDirectory: = PChar (ExtractFilePath (ExeName)); SEI.lpParameters: = PChar (Params); SEI.lpVerb: = PChar ("runas"); SEI.fMask: = SEE_MASK_NOCLOSEPROCESS; SEI.nShow: = SW_SHOWNORMAL; Win32Check (ShellExecuteEx (@SEI)); try Result: = WaitForSingleObject (SEI.hProcess, Timeout) = WAIT_OBJECT_0; if Result and (@ExitCode <> nil) then Win32Check (GetExitCodeProcess (SEI.hProcess, ExitCode)); finally CloseHandle (SEI.hProcess); end; end;



AlexeyTG   (2014-12-19 21:15) [7]

Rouse_ ©
Enclose the path to the software in quotation marks, it is written about this both in MSDN and with the article you cited


> Forget about quotes or put extra ones. Quotation marks are needed in
> command line (second parameter CreateProcess) and not needed
> in the module name (first parameter).


If RunApp ("C: \ Windows \ System32 \ cmd.exe", ""/?"") then
RunApp ("C: \ Windows \ System32 \ notepad.exe", ""D: \ 1.txt"");
It turns out so?

Anyway, remove Application.Terminate - why do you need it here? -> again I read that after it frees resources from memory.


quotedXNUMX>> it will be so normal? :)
>
> No, of course :)

and how then? :(



Rouse_ ©   (2014-12-19 21:21) [8]


> It turns out so?

Not so - quotation marks are not there.


> again I read that after it frees resources from
> memory.

It is already free - you do not need to control the application so rudely.


> how then? :(

I’ll take any of the functions I have given and use it to call.



AlexeyTG   (2014-12-19 21:34) [9]

if ExecAndWait ("C: \ Windows \ System32 \ cmd.exe", "/?",
and what other parameters what to specify? :(



Rouse_ ©   (2014-12-19 21:37) [10]

Well, declare ExitCode: Cardinal, and pass it on.



AlexeyTG   (2014-12-19 21:45) [11]

I read what Cardinal is :) I can not figure it out. You can poke straight lines of code an example of a call and what to add :(



AlexeyTG   (2014-12-19 21:51) [12]

var ExitCode: Cardinal; if ExecAndWait ("CMD.EXE", "/?", ExitCode) then



AlexeyTG   (2014-12-19 21:55) [13]

program Project1; uses Vcl.Forms, Winapi.Windows, System.SysUtils; Var StartInf: TStartupInfo; ProcInf: TProcessInformation; CmdLine: String; Timeout: Cardinal; {$ R * .res} // Normal start of the process and waiting for its completion function ExecAndWait (const ExeName, Params: string; out ExitCode: Cardinal; Timeout: Cardinal = MaxInt): boolean; var sui: TStartupInfo; pi: TProcessInformation; begin ZeroMemory (@sui, SizeOf (sui)); sui.cb: = SizeOf (sui); Win32Check (CreateProcess (nil, PChar ("" "+ ExeName +" "" + Params), nil, nil, False, 0, nil, nil, sui, pi)); try CloseHandle (pi.hThread); Result: = WaitForSingleObject (pi.hProcess, Timeout) = WAIT_OBJECT_0; if Result and (@ExitCode <> nil) then Win32Check (GetExitCodeProcess (pi.hProcess, ExitCode)); finally CloseHandle (pi.hProcess); end; end; begin If ExecAndWait ("C: \ Windows \ System32 \ cmd.exe", "/?", Timeout) then ExecAndWait ("C: \ Windows \ System32 \ notepad.exe", "D: \ 1.txt", Timeout) else Application.Terminate; end.



AlexeyTG   (2014-12-19 21:56) [14]

Is this an option?



Rouse_ ©   (2014-12-19 22:04) [15]

Not right :)
Do this:

program Project1; {$ APPTYPE CONSOLE} {$ R * .res} uses Windows SysUtils function ExecAndWait (const ExeName, Params: string; out ExitCode: Cardinal; Timeout: Cardinal = MaxInt): boolean; var sui: TStartupInfo; pi: TProcessInformation; begin ZeroMemory (@sui, SizeOf (sui)); sui.cb: = SizeOf (sui); Win32Check (CreateProcess (nil, PChar ("" "+ ExeName +" "" + Params), nil, nil, False, 0, nil, nil, sui, pi)); try CloseHandle (pi.hThread); Result: = WaitForSingleObject (pi.hProcess, Timeout) = WAIT_OBJECT_0; if Result and (@ExitCode <> nil) then Win32Check (GetExitCodeProcess (pi.hProcess, ExitCode)); finally CloseHandle (pi.hProcess); end; end; var ExitCode: Cardinal; begin try if not ExecAndWait ("C: \ Windows \ System32 \ cmd.exe", "/?", ExitCode) then RaiseLastOSError; if ExitCode <> 0 then Writeln ("Wrong exit code:", ExitCode); if not ExecAndWait ("C: \ Windows \ System32 \ notepad.exe", "D: \ 1.txt", ExitCode) then RaiseLastOSError; if ExitCode <> 0 then Writeln ("Wrong exit code:", ExitCode); except on E: Exception do Writeln (E.ClassName, ":", E.Message); end; Readln end.



AlexeyTG   (2014-12-19 22:11) [16]

Rouse_ © Suffered the finished source is called: D

Something is happening when starting this option. It directly opens CMD in itself, and after several keystrokes (scrolling help text) in the same window writes
Special characters that require mandatory quotation marks: <space> & () [] {} ^ = ;! "+,` ~ Wrong exit code: 1
and launches notepad



AlexeyTG   (2014-12-19 22:13) [17]

Sorry, got it :) changed cmd to another EX



AlexeyTG   (2014-12-19 22:16) [18]

I only do not need a console application. You just need the EXT to launch the other two. Without own window and data output :) As I wrote here
http://delphimaster.net/view/2-1418843283/



Rouse_ ©   (2014-12-19 22:17) [19]

Of course - this is the console :)
Turn off console generation in the linker settings and comment out the {$ APPTYPE CONSOLE} directive, then if you try to output text to the console you will get this exception:

--------------------------- Debugger Exception Notification --------------------------- Project Project7.exe raised exception class EInOutError with message "I / O error 105". --------------------------- Break Continue Help ---------------------------



Rouse_ ©   (2014-12-19 22:19) [20]

Well then, rewrite the start code like this (you don’t need to analyze the return code, as I understand it):

program Project1; {$ R * .res} uses Windows SysUtils function ExecAndWait (const ExeName, Params: string; out ExitCode: Cardinal; Timeout: Cardinal = MaxInt): boolean; var sui: TStartupInfo; pi: TProcessInformation; begin ZeroMemory (@sui, SizeOf (sui)); sui.cb: = SizeOf (sui); Win32Check (CreateProcess (nil, PChar ("" "+ ExeName +" "" + Params), nil, nil, False, 0, nil, nil, sui, pi)); try CloseHandle (pi.hThread); Result: = WaitForSingleObject (pi.hProcess, Timeout) = WAIT_OBJECT_0; if Result and (@ExitCode <> nil) then Win32Check (GetExitCodeProcess (pi.hProcess, ExitCode)); finally CloseHandle (pi.hProcess); end; end; begin if not ExecAndWait ("C: \ Windows \ System32 \ cmd.exe", "/?", PCardinal (nil) ^) then RaiseLastOSError; if not ExecAndWait ("C: \ Windows \ System32 \ notepad.exe", "D: \ 1.txt", PCardinal (nil) ^) then RaiseLastOSError; end.



Rouse_ ©   (2014-12-19 22:25) [21]

Well, I hope everything is clear?
And then I want to relax already on Friday :)



AlexeyTG   (2014-12-19 22:32) [22]

Rouse_ Yes, thank you HUGE for your help.
Just for general development already, it turns out almost the same code that I wrote in the first message, only CloseHandle transferred to the function?
and the second question is RaiseLastOSError what does it do? :)



AlexeyTG   (2014-12-19 22:35) [23]

Well, CreateProcess is called differently.

What is Win32Check?



Rouse_ ©   (2014-12-19 22:42) [24]


> only CloseHandle transferred to function?

Uh-huh.


> and the second question is RaiseLastOSError what does it do? :)

Raises exception based on last error code


> What is Win32Check?

checks the return code, and if something is wrong, raises RaiseLastOSError.

Mustache - ran away, for other questions read the help, everything is there :)



AlexeyTG   (2014-12-19 22:58) [25]

Rouse_ OK, thank you very much for the TIME first of all :)

___ I will try to rewrite my own based on this code, because therefore if the file cannot be found, then an application error, and not just an exit :)



Pages: 1 whole branch

Forum: "Beginners";
Current archive: 2017.01.15;
Download: [xml.tar.bz2];

Top





Memory: 0.66 MB
Time: 0.09 c
15-1451856604
Jury
2016-01-04 00:30
2017.01.15
Happy Birthday ! 4 January 2016 Monday


15-1453757404
Jury
2016-01-26 00:30
2017.01.15
Happy Birthday ! 26 January 2016 Tuesday


2-1423343442
Andrey K
2015-02-08 00:10
2017.01.15
How to work with the LAN port


15-1447936212
Kerk
2015-11-19 15:30
2017.01.15
Preservation of the position and size of the form


2-1425123097
SergP
2015-02-28 14:31
2017.01.15
Heirs of abstract classes





afrikaans albanian Arabic armenian azerbaijani basque belarusian bulgarian catalan Chinese (Simplified) Chinese (Traditional) croatian Czech danish Dutch English estonian filipino finnish French
galician georgian German greek haitian Creole hebrew Hindi hungarian icelandic Indonesian Irish italian Japanese Korean latvian lithuanian macedonian malay maltese norwegian
persian polish portuguese Romanian russian serbian slovak Slovenian Spanish swahili Swedish ภาษาไทย turkish Ukrainian urdu Tiếng Việt welsh yiddish bengali bosnian
cebuano Esperanto gujarati hausa hmong igbo javanese kannada Khmer lao latin maori marathi mongolian nepali punjabi somali tamil telugu yoruba
zulu
English French German Italian Portuguese Russian Spanish