//****************API Iterate Tester************************** program Rapid_API_AGSI_Get_Post1_plus; //https://www.techtarget.com/searchapparchitecture/definition/OpenAPI-Specification //https://agsi.gie.eu/api //https://rapidapi.com/maxkleiner1/api/maxbox4/tutorials //ct.de/y4 //#TODO: right axis full [%] done - changed full from int2double Const X_Rapidapi_Key = 'df61a35825msh66c95e953a7ap192bcfjsn16a_________'; SUserAgent = 'Mozilla/5.001 (windows; U; NT4.0; en-US; rv:1.0) Gecko/25250101'; USERAGENTE = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0'; URLMALWARE ='http://malware.testing.google.test/testing/malware/'; //'http://chart.apis.google.com/chart?chs=%dx%d&cht=qr&chld=%s&chl=%s'; //Const /search?term=kiss%20the%20rain&locale=en-US&offset=0&limit=5 HTTP/1.1 procedure Form_CloseClick(Sender: TObject; var action: TCloseAction); forward; Const PYHOME32 = 'C:\Users\max\AppData\Local\Programs\Python\Python36-32\'; procedure getURLScanAPI_Python(ftopic: string); begin with TPythonEngine.Create(Nil) do begin pythonhome:= PYHOME32; loadDLL(); try Execstring('import urllib.request, json, requests'); ExecStr('headers={"Content-Type":"application/json"}') ExecStr('data = {"url": "'+ftopic+'", "visibility": "public"}') ExecStr('resp = requests.post("https://urlscan.io/api/v1/scan/",headers=headers, '+ 'data=json.dumps(data))'); Print(EvalStr('resp')); print(EvalStr('resp.json()')); except raiseError; finally //unloadDll; Free; end; end; end; Const WeatherAPIKEY='55013bf3d09cfb0619989a00ed5bed09'; URLWeatherAPI='https://api.openweathermap.org/data/2.5/weather?q=%s&units=metric&appid=%s'; function GetWeatherStreamJSON(const Data, APIKEY: string): string; var encodURL: string; mapStrm: TStringStream; jo: TJSONObject; begin encodURL:= Format(URLWeatherAPI,[HTTPEncode(Data), APIKEY]); mapStrm:= TStringStream.create(''); try HttpGet(EncodURL, mapStrm); //WinInet mapStrm.Position:= 0; jo:= TJSONObject.Create4(mapStrm.datastring); result:= jo.getjsonarray('weather').getjsonobject(0).getstring('description'); result:= result+' '+jo.getjsonobject('main').getstring('temp'); except writeln('Error: '+mapstrm.datastring); writeln('E: '+ExceptiontoString(exceptiontype, exceptionparam)); finally mapStrm.Free; encodURL:= ''; jo.Free; end; end; Const //please get your api key first: https://agsi.gie.eu/account AGSI_APIKEY='16600670617ff72de59403f2a4bbb92f'; URL_AGSIAPI='https://agsi.gie.eu/api?country=%s&from=%s&size=%s&x-key:%s'; URL_AGSIAPI2='https://agsi.gie.eu/api?country=%s&from=%s&size=%s'; function GetEnergyStreamJSON(const Data, APIKEY: string): string; var encodURL: string; mapStrm: TStringStream; jo: TJSONObject; asp: TStringArray; begin asp:= splitstr(data,','); encodURL:= Format(URL_AGSIAPI,[HTTPEncode(asp[0]),asp[1],asp[2],APIKEY]); writeln(encodURL) mapStrm:= TStringStream.create(''); try HttpGet(EncodURL, mapStrm); //WinInet mapStrm.Position:= 0; jo:= TJSONObject.Create4(mapStrm.datastring); writeln(jo.getstring('data')); result:= jo.getjsonarray('data').getjsonobject(0).getstring('name'); result:= result+' '+jo.getjsonobject('full').getstring('full'); except writeln('Error: '+mapstrm.datastring); writeln('E: '+ExceptiontoString(exceptiontype, exceptionparam)); finally mapStrm.Free; encodURL:= ''; jo.Free; end; end; // plot functions--------------------------------------------------------// var plotform: TForm; procedure Form_CloseClick(Sender: TObject; var action: TCloseAction); begin //afrm.Close; action:= cafree; //chart1.Free; writeln('EPlotform closed at: '+datetimetostr(now)); end; //http://www.teechart.net/docs/teechart/vclfmx/lib/html/TBarSeries.html function ChartInjector(aform: Tform): TChart; var Ser1: TBarSeries; //TPieSeries, TFastLineSeries; ser2: TLineSeries; begin result:= TChart.create(aform) with result do begin parent:= aform; align:= alClient; Title.Text.add('Sciplot: '+'GAS Injection / Full DE 2022 Ĝ'); LeftAxis.Title.Caption:= 'Injection GWh/d Amount'; RightAxis.Title.Caption:= 'Fulls in [%]'; Title.font.size:= 15; Ser1:= TBarSeries.create(result); // TPieSeries ser1.parentchart:= result; ser1.Marks.Visible := False //serUllage.VertAxis := aRightAxis; Legend.CheckBoxes:= True; RightAxis.SetMinMax(0, 100); LeftAxis.SetMinMax(0, 2000); Ser1.ShowInLegend:= True; ser1.title:= 'Injects' Ser2:= TLineSeries.create(result); ser2.VertAxis := aRightAxis; //ser2.axis.automatic := 0; ser2.parentchart:= result; ser2.SeriesColor:= clRed; ser2.title:= 'Full [%]' //ser2.YValues.Multiplier:= 100; View3D := False; //Axes.Bottom.DateTimeFormat:= 'dd/mmm/yy'; //Free; end; end; procedure JSON2Plot(form1: TForm; alocate: TJSONArray); var chart1: TChart; cnt: integer; sumup, tmp2,tmp: double; begin form1.onclose:= @Form_CloseClick; chart1:= ChartInjector(form1); sumup:=0; tmp2:=0; tmp:=0; try for cnt:= 0 to alocate.length-1 do begin //writeln(locate.getjsonobject(it).getstring('gasDayStart')+':'+ tmp:= alocate.getjsonobject(alocate.length-1-cnt).getdouble('injection'); tmp2:= alocate.getjsonobject(alocate.length-1-cnt).getdouble('full'); sumup:= sumup+tmp; chart1.Series[0].Addxy(cnt,tmp,'',clgreen); chart1.Series[1].Addxy(cnt,tmp2,'',clred); end; except writeln('EPlot: '+ExceptiontoString(exceptiontype, exceptionparam)); end; PrintF(' Landrange %d: Injection sum: %.2f', [alocate.length-1, sumup]); end; function letGenerateJSON2(HttpRqresponseText: string): TJSONArray; var jo: TJSONObject; begin jo:= TJSONObject.Create4(HttpRqresponseText); try //writeln(jo.getstring('data')); writeln(itoa(jo.getjsonarray('data').getjsonobject(0).length)) writeln(itoa(jo.getjsonarray('data').length)) result:= jo.getjsonarray('data'); //write out to check for it:= 0 to result.length-1 do writeln(result.getjsonobject(it).getstring('gasDayStart')+':'+ result.getjsonobject(it).getstring('injection')); except writeln('EJson: '+ExceptiontoString(exceptiontype, exceptionparam)); end; end; function getEnergyStreamJSON2(AURL, feedstream, aApikey: string): string; var encodURL: string; httpRq,hr: Olevariant; asp: TStringArray; begin httpRq:= CreateOleObject('WinHttp.WinHttpRequest.5.1'); // Opens HTTPs connection. try asp:= splitStr(feedstream,','); encodURL:= Format(AURL,[HTTPEncode(asp[0]),(asp[1]),asp[2]]); writeln(encodurl) hr:= httpRq.Open('GET', encodURL, false); httpRq.setRequestheader('user-agent',USERAGENTE); httpRq.setRequestheader('x-key',aAPIkey); if hr= S_OK then HttpRq.Send(); If HttpRq.Status = 200 Then result:= HttpRq.responseText Else result:= 'Failed getting response:'+itoa(HttpRq.Status)+HttpRq.responseText; //writeln('debug response: '+HttpReq.GetAllResponseHeaders); except writeln('Error: '+HttpRq.responseText); writeln('EHTTP: '+ExceptiontoString(exceptiontype, exceptionparam)); finally httprq:= unassigned; end; end; //https://github.com/Zeus64/alcinoe/blob/master/source/ALHttpClient.pas //http://www.softwareschule.ch/examples/alhttpclient2.txt function TALHTTPClient_Get(aUrl: AnsiString; feedstream, aApikey: string): string; Var LHttpClient: TALWininetHttpClient; asp: TStringArray; begin LHttpClient:= TALWininetHttpClient.create; asp:= splitStr(feedstream,','); LHttpClient.url:= Format(AURL,[HTTPEncode(asp[0]),(asp[1]),asp[2]]); LHttpClient.RequestMethod:= HTTPmt_Get; //HTTPrm_Post; LHttpClient.RequestHeader.UserAgent:=USERAGENTE; //LHttpClient.RequestHeader.CustomHeaders:= LHttpClient.RequestHeader.RawHeaderText:='x-key:'+aAPIkey; try result:= LHttpClient.Get1(LHttpClient.url); //overload; finally LHttpClient.Free; end; end; const ESCAPE_CHAR = '\'; QUOTE_CHAR = '"'; EXCEPTION_FMT = 'Invalid escape at position %d'; function JSONUnescape(const Source: string; CRLF: string {= #13#10}): string; var EscapeCharPos, TempPos: Integer; Temp: string; IsQuotedString: Boolean; begin if CRLF = '' then CRLF:= #13#10; result:= ''; IsQuotedString:= (Source[1] = QUOTE_CHAR) and (Source[Length(Source)] = QUOTE_CHAR); EscapeCharPos:= Pos(ESCAPE_CHAR, Source); TempPos:= 1; while EscapeCharPos > 0 do begin result:= result + Copy(Source, TempPos, EscapeCharPos - TempPos); TempPos:= EscapeCharPos; if EscapeCharPos < Length(Source) - booltoint(IsQuotedString) then case Source[EscapeCharPos + 1] of 't': Temp:= #9; 'n': Temp:= CRLF; '\': Temp:= '\'; '"': Temp:= '"'; 'u': begin if EscapeCharPos + 4 < Length(Source) - Integer(IsQuotedString) then Temp := Chr(StrToInt('$' + Copy(Source, EscapeCharPos + 2, 4))) else begin raise Exception.Create(Format(EXCEPTION_FMT, [EscapeCharPos])); end; Inc2(TempPos, 4); end; else begin Xraise (Exception.Create(Format(EXCEPTION_FMT, [EscapeCharPos]))); end; end else begin Xraise (Exception.Create(Format(EXCEPTION_FMT, [EscapeCharPos]))); end; Inc2(TempPos, 2); result:= result + Temp; EscapeCharPos:= PosEx(ESCAPE_CHAR, Source, TempPos); end; result:= result + Copy(Source, TempPos, Length(Source) - TempPos + 1); end; //ĦĦĦĦĦĦĦĦĦĦPlease be nice and use your own API key, get a key from here http://code.google.com/apis/safebrowsing/key_signup.html ĦĦĦĦĦĦĦĦĦĦ const GoogleApiKey = 'AIzaSyAqJ4-ltjzzbJnYLI05WCHqj_1ODVOY6__'; var JTESTDATA: string; procedure setTestData; begin JTESTDATA:= '{ '+LF+ '"client": { '+LF+ ' "clientId": "TestClient4", '+LF+ ' "clientVersion": "1.1" '+LF+ '}, '+LF+ '"threatInfo": { '+LF+ ' "threatTypes": ["MALWARE", "SOCIAL_ENGINEERING"],'+LF+ ' "platformTypes": ["LINUX"], '+LF+ ' "threatEntryTypes": ["URL"], '+LF+ ' "threatEntries": [ '+LF+ ' {"url": "%s"} '+LF+ ' ] '+LF+ ' } '+LF+ '}'; end; function getPostGoogleAPI(feedstream, aApikey, tolang: string): string; var Url,aAPI_KEY, source: string; jo, locate: TJSONObject; httpRq,hr: Olevariant; strm: TStringStream; begin //setTestData before; httpRq:= CreateOleObject('WinHttp.WinHttpRequest.5.1'); // Open HTTPs connection. try hr:= httpRq.Open('POST','https://safebrowsing.googleapis.com/v4/threatMatches:find?key=' +aApikey, false); httpRq.setRequestheader('user-agent',SUSERAGENT ); httpRq.setRequestheader('content-type','application/json'); if hr= S_OK then HttpRq.Send(format(JTESTDATA,[feedstream])); //writeln(format(JTESTDATA,[feedstream])); If HttpRq.Status = 200 Then result:= HttpRq.responseText Else result:= 'Failed at getting response:'+itoa(HttpRq.Status)+HttpRq.responseText; //writeln('debug response '+HttpReq.GetAllResponseHeaders); finally httprq:= unassigned; end; end; var HttpResponse: string; begin //@main //maxform1.ShellStyle1click(self) maxform1.Console1Click(self) //writeln(getMusicAPI_Com('kiss the rain' ,'en-US', 3)); //writeln(JSONUnescape('"\u2764Love\tAPI\u2764"', #13#10)); // {= #13#10}) //writeln(JSONUnescape('\\\Invalid escaped text','')); //TALMultipartFormDataDecoder //ALMultipartExtractBoundaryFromContentType //ALBase64EncodeStringMIME // ALHTTPdecode //TAlWinInetHTTPClientStatusEvent writeln('back from weatherjs: '+GetWeatherStreamJSON('Bern,CH',WeatherAPIKEY)); //writeln(itoa(JExecute('cmd /C dir *.*',@TTextHandlerQ, true, false))); //writeln(GETDOSOutput('cmd.exe /c wmic cpu get architecture','C:\')); //writeln(itoa(JExecute('cmd /c netstat -o',@TTextHandlerQ, true, false))); //Webbrowser1.Document.QueryInterface(IHTMLDocument2, iDoc); //ExecuteScript(iDoc, 'document.login.submit()', 'JavaScript'); //writeln(getwapi) procedure GetDNSServers(AList: TStringList); GetDNSServers getIPs getips; setTestData; { with TJson.create do begin JTESTDATA:= format(JTESTDATA,['www.ibm.ch']); parse(JTESTDATA); writeln(Stringify); clear; free; end; } //writeln('GPost: '+getPostGoogleAPI('http://www.urltocheck1.org/',GoogleApiKey,'')); // writeln('GPost: '+getPostGoogleAPI(URLMALWARE, GoogleApiKey,'')); //writeln('GPost: '+getPostGoogleAPI(URLMALWARE, sApiKey,'')); with TJson.create do begin parse(JTESTDATA); writeln(Stringify); clear; free; end; { Note: If there are no matches (that is, if none of URLs specified in request are found on any of lists specified in a request), HTTP POST response simply returns empty object in response body. } // writeln('GPost: '+getPostGoogleAPI('http://www.ibm.ch', GoogleApiKey,'')); // getURLScanAPI_Python('www.ibm.ch'); // writeln(GetEnergyStreamJSON('DE,2022-03-01,20',AGSI_APIKEY)); plotform:= getForm2(1400, 600, clsilver, 'Sciplot4'); plotform.icon.loadfromresourcename(hinstance,'ZHISTOGRAM'); HttpResponse:= getEnergyStreamJSON2(URL_AGSIAPI2,'DE,2022-01-03,300',AGSI_APIKEY); JSON2Plot(plotform, letGenerateJSON2(HttpResponse)); //writeln(TALHTTPClient_Get(URL_AGSIAPI2,'DE,2022-01-03,10',AGSI_APIKEY)); End. Ref history: [] Error: {"last_page":0,"total":0,"dataset":"storage ERROR","error":"access denied","message":"Invalid or missing API key","data":[]} E: Exception: TJSONArray[0] not found. get a api key first: https://agsi.gie.eu/account HttpClient httpclient = new DefaultHttpClient(); HttpGet request = new HttpGet(theUrl); request.addHeader("x-api-key", apiKey); HttpResponse response = httpclient.execute(request); https://stackoverflow.com/questions/5334997/rest-get-requests-verbs-and-apikey Doc: https://rapidapi.com/collection/list-of-free-apis https://algosim.org/SynViewSource/ https://stackoverflow.com/questions/37410849/safe-browsing-lookup-api-v4-invalid-json-payload-received log doc: GPost: Failed at getting response:403{ "error": { "code": 403, "message": "The request is missing a valid API key.", "status": "PERMISSION_DENIED" } } GPost: Failed at getting response:400{ "error": { "code": 400, "message": "API key not valid. Please pass a valid API key.", "status": "INVALID_ARGUMENT", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "API_KEY_INVALID", "domain": "googleapis.com", "metadata": { "service": "safebrowsing.googleapis.com" } } ] } } GPost: Failed at getting response:403{ "error": { "code": 403, "message": "Safe Browsing API has not been used in project 338972382324 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/safebrowsing.googleapis.com/overview?project=338972382324 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.", "status": "PERMISSION_DENIED", "details": [ { "@type": "type.googleapis.com/google.rpc.Help", "links": [ { "description": "Google developers console API activation", "url": "https://console.developers.google.com/apis/api/safebrowsing.googleapis.com/overview?project=338972382324" } ] }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "SERVICE_DISABLED", "domain": "googleapis.com", "metadata": { "service": "safebrowsing.googleapis.com", "consumer": "projects/338972382324" } } ] } } https://stackoverflow.com/questions/5661596/do-i-need-a-content-type-header-for-http-get-requests As far as I understood there are two places where to set the content type: The client sets a content type for the body he is sending to the server (e.g. for post) The server sets a content type for the response. A sender that generates a message containing a payload body SHOULD generate a Content-Type header field in that message unless the intended media type of the enclosed representation is unknown to the sender. If a Content-Type header field is not present, the recipient MAY either assume a media type of "application/octet-stream" ([RFC2046], Section 4.5.1) or examine the data to determine its type. It means that the Content-Type HTTP header should be set only for PUT and POST requests. GET requests can have "Accept" headers, which say which types of content the client understands. The server can then use that to decide which content type to send back. writeln(GETDOSOutput('cmd.exe /c wmic cpu get architecture','C:\')); writeln(GETDOSOutput('cmd.exe /c wmic cpu get name','C:\')); //to monitor tcp spyware over PID - process ID memo2.setFocus; repeat writeln(GETDOSOutput('cmd.exe /c netstat -o','C:\')); memo2.color:= clsilver; sleep(2000) memo2.color:= clyellow; until isKeyPressed; memo2.color:= clwhite; writeln(SysErrorMessage(GetLastError)) Doc: TALWininetHttpClient TALWinInetHttpClient is a is easy to use WinInet-based. HTTP client component which allows to post and get. any data from the Web via HTTP protocol. https://svn.code.sf.net/p/alcinoe/code/demos/ALWinInetHTTPClient/_source/Unit1.pas https://docwiki.embarcadero.com/Libraries/Sydney/en/System.Net.HttpClient.THTTPClient.Post https://stackoverflow.com/questions/9713491/delphi-decode-json-utf8-escaped-text 12 \uXXXX is the JSON Unicode escape notation (X is hexadecimal). ref: -------------------------------------------------------- TWinApiDownload = class(TObject) private fEventWorkStart : TEventWorkStart; fEventWork : TEventWork; fEventWorkEnd : TEventWorkEnd; fEventError : TEventError; fURL : string; fUserAgent : string; fStop : Boolean; fActive : Boolean; fCachingEnabled : Boolean; fProgressUpdateInterval : Cardinal; function GetIsActive : Boolean; public constructor Create; destructor Destroy; override; function CheckURL(aURL: string) : Integer; function Download(Stream : TStream) : Integer; overload; function Download(var res : string) : Integer; overload; function ErrorCodeToMessageString(aErrorCode : Integer) : string; procedure Stop; procedure Clear; property UserAgent : string read fUserAgent write fUserAgent; property URL : string read fURL write fURL; property DownloadActive : Boolean read GetIsActive; property CachingEnabled : Boolean read fCachingEnabled write fCachingEnabled; property UpdateInterval:Cardinal read fProgressUpdateInterval write fProgressUpdateInterval; property OnWorkStart : TEventWorkStart read fEventWorkStart write fEventWorkStart; property OnWork : TEventWork read fEventWork write fEventWork; property OnWorkEnd : TEventWorkEnd read fEventWorkEnd write fEventWorkEnd; property OnError : TEventError read fEventError write fEventError; end; procedure SIRegister_TJSONObject(CL: TPSPascalCompiler); begin //with RegClassS(CL,'TZAbstractObject', 'TJSONObject') do with CL.AddClassN(CL.FindClass('TZAbstractObject'),'TJSONObject') do begin RegisterMethod('Constructor create;'); RegisterMethod('Constructor create1( jo : TJSONObject; sa : array of string);'); RegisterMethod('Constructor create2( x : JSONTokener);'); RegisterMethod('Constructor create3( map : TStringList);'); RegisterMethod('Constructor create4( s : string);'); RegisterMethod('Procedure clean'); Function clone : TZAbstractObject'); Function accumulate( key : string; value : TZAbstractObject) : TJSONObject'); Function get( key : string) : TZAbstractObject'); Function getBoolean( key : string) : boolean'); Function getDouble( key : string) : double'); Function getInt( key : string) : integer'); Function getJSONArray( key : string) : TJSONArray'); Function getJSONObject( key : string) : TJSONObject'); Function getString( key : string) : string'); Function has( key : string) : boolean'); Function isNull( key : string) : boolean'); Function keys : TStringList'); Function length : integer'); Function names : TJSONArray'); Function numberToString( n : _Number) : string'); Function valueToString( value : TZAbstractObject) : string;'); Function valueToString1( value : TZAbstractObject; indentFactor, indent : integer) : string;'); Function opt( key : string) : TZAbstractObject'); Function optBoolean( key : string) : boolean;'); Function optBoolean1( key : string; defaultValue : boolean) : boolean;'); Function optDouble( key : string) : double;'); Function optDouble1( key : string; defaultValue : double) : double;'); Function optInt( key : string) : integer;'); Function optInt1( key : string; defaultValue : integer) : integer;'); Function optString( key : string) : string;'); Function optString1( key : string; defaultValue : string) : string;'); Function optJSONArray( key : string) : TJSONArray;'); Function optJSONObject( key : string) : TJSONObject;'); Function put( key : string; value : boolean) : TJSONObject;'); Function put1( key : string; value : double) : TJSONObject;'); Function put2( key : string; value : integer) : TJSONObject;'); Function put3( key : string; value : string) : TJSONObject;'); Function put4( key : string; value : TZAbstractObject) : TJSONObject;'); Function putOpt( key : string; value : TZAbstractObject) : TJSONObject'); Function quote( s : string) : string'); Function remove( key : string) : TZAbstractObject'); Procedure assignTo( json : TJSONObject)'); Function toJSONArray( names : TJSONArray) : TJSONArray'); Function toString1( indentFactor : integer) : string;'); Function toString2( indentFactor, indent : integer) : string;'); RegisterMethod('Function NULL : NULL'); end; end; E: Exception: Access violation at address 01F0CC04 in module 'maXbox4.exe'. Read of address 00000000. Failed at getting response:415HTTP 415 Unsupported Media Type Failed at getting response: 503503 - Service Unavailable C:\maXbox\works2021\maxbox4>py Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD6 4)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import http.client >>> >>> conn = http.client.HTTPSConnection("nlp-translation.p.rapidapi.com") >>> payload = "text=Hello%20World&to=es&from=en" >>> headers = { ... 'content-type': "application/x-www-form-urlencoded", ... 'X-RapidAPI-Host': "nlp-translation.p.rapidapi.com", ... 'X-RapidAPI-Key': "df61a35825msh66c9514de953a7ap192bcfjsn16a3d1018ce3" ... } >>> conn.request("POST", "/v1/translate", payload, headers) >>> >>> res = conn.getresponse() >>> data = res.read() >>> print(data.decode("utf-8")) {"message":"You are not subscribed to this API."} >>> Failed at getting response: 503503 - Service Unavailable Passwort checker? https://haveibeenpwned.com https://dnslytics.com/spf-lookup procedure RunDosInMemo(DosApp: string; AMemo:TMemo); const READ_BUFFER_SIZE = 2400; var Security: TSecurityAttributes; readableEndOfPipe, writeableEndOfPipe: THandle; start: TStartUpInfo; ProcessInfo: TProcessInformation; Buffer: PAnsiChar; BytesRead: DWORD; AppRunning: DWORD; begin Security.nLength := SizeOf(TSecurityAttributes); Security.bInheritHandle := True; Security.lpSecurityDescriptor := nil; if CreatePipe({var}readableEndOfPipe, {var}writeableEndOfPipe, @Security, 0) then begin Buffer := AllocMem(READ_BUFFER_SIZE+1); FillChar(Start, Sizeof(Start), #0); start.cb := SizeOf(start); // Set up members of the STARTUPINFO structure. // This structure specifies the STDIN and STDOUT handles for redirection. // - Redirect the output and error to the writeable end of our pipe. // - We must still supply a valid StdInput handle (because we used STARTF_USESTDHANDLES to swear that all three handles will be valid) start.dwFlags := start.dwFlags or STARTF_USESTDHANDLES; start.hStdInput := GetStdHandle(STD_INPUT_HANDLE); //we're not redirecting stdInput; but we still have to give it a valid handle start.hStdOutput := writeableEndOfPipe; //we give the writeable end of the pipe to the child process; we read from the readable end start.hStdError := writeableEndOfPipe; //We can also choose to say that the wShowWindow member contains a value. //In our case we want to force the console window to be hidden. start.dwFlags := start.dwFlags + STARTF_USESHOWWINDOW; start.wShowWindow := SW_HIDE; // Don't forget to set up members of the PROCESS_INFORMATION structure. ProcessInfo := Default(TProcessInformation); //WARNING: The unicode version of CreateProcess (CreateProcessW) can modify the command-line "DosApp" string. //Therefore "DosApp" cannot be a pointer to read-only memory, or an ACCESS_VIOLATION will occur. //We can ensure it's not read-only with the RTL function: UniqueString UniqueString({var}DosApp); if CreateProcess(nil, PChar(DosApp), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, start, {var}ProcessInfo) then begin //Wait for the application to terminate, as it writes it's output to the pipe. //WARNING: If the console app outputs more than 2400 bytes (ReadBuffer), //it will block on writing to the pipe and *never* close. repeat Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 100); Application.ProcessMessages; until (Apprunning <> WAIT_TIMEOUT); //Read the contents of the pipe out of the readable end //WARNING: if the console app never writes anything to the StdOutput, then ReadFile will block and never return repeat BytesRead := 0; ReadFile(readableEndOfPipe, Buffer[0], READ_BUFFER_SIZE, {var}BytesRead, nil); Buffer[BytesRead]:= #0; OemToAnsi(Buffer,Buffer); AMemo.Text := AMemo.text + String(Buffer); until (BytesRead < READ_BUFFER_SIZE); end; FreeMem(Buffer); CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); CloseHandle(readableEndOfPipe); CloseHandle(writeableEndOfPipe); end; end; procedure TForm1.Button1Click(Sender: TObject); begin {button 1 code} RunDosInMemo('chkdsk.exe c:\',Memo1); end; CL.AddDelphiFunction('procedure RunDosInMemo(DosApp: string; AMemo:TMemo);'); ShellExecute(0, 'open', Pchar('DocumentName.pdf'), '', '', SW_SHOWNORMAL); work under Windows 7 and 8, which would start the Acrobat Reader and open the file but under Windows 10 this no longer is the case. So the next step was to update the call to use ShellExecuteEX instead. ShellInfo := Default(TShellExecuteInfo); ShellInfo.cbSize := SizeOf(TShellExecuteInfo); ShellInfo.lpFile := PChar(Current_Client_Documents + FileName +'.pdf'); ShellInfo.nShow := SW_SHOWNORMAL; try ShellExecuteEx(@ShellInfo); The actual code will prepare the Object ShellInfo to contain all of the necessary data to start up the Acrobat Reader and display the generated PDF. //make a GET request using the WinInet functions function Https_Get(const ServerName,Resource : string;Var Response:AnsiString): Integer; const BufferSize=1024*64; var hInet : HINTERNET; hConnect : HINTERNET; hRequest : HINTERNET; ErrorCode : Integer; lpvBuffer : PAnsiChar; lpdwBufferLength: DWORD; lpdwReserved : DWORD; dwBytesRead : DWORD; lpdwNumberOfBytesAvailable: DWORD; begin Result :=0; Response:=''; hInet := InternetOpen(PChar(sUserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); if hInet=nil then begin ErrorCode:=GetLastError; raise Exception.Create(Format('InternetOpen Error %d Description %s', [ErrorCode,GetWinInetError(ErrorCode)])); end; try hConnect := InternetConnect(hInet, PChar(ServerName), INTERNET_DEFAULT_HTTPS_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 0); if hConnect=nil then begin ErrorCode:=GetLastError; raise Exception.Create(Format('InternetConnect Error %d Description %s',[ErrorCode,GetWinInetError(ErrorCode)])); end; try //make the request hRequest := HttpOpenRequest(hConnect, 'GET', PChar(Resource), HTTP_VERSION, '', nil, INTERNET_FLAG_SECURE, 0); if hRequest=nil then begin ErrorCode:=GetLastError; raise Exception.Create(Format('HttpOpenRequest Error %d Description %s',[ErrorCode,GetWinInetError(ErrorCode)])); end; try //send the GET request if not HttpSendRequest(hRequest, nil, 0, nil, 0) then begin ErrorCode:=GetLastError; raise Exception.Create(Format('HttpSendRequest Error %d Description %s',[ErrorCode,GetWinInetError(ErrorCode)])); end; lpdwBufferLength:=SizeOf(Result); lpdwReserved :=0; //get the status code if not HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE or HTTP_QUERY_FLAG_NUMBER, @Result, lpdwBufferLength, lpdwReserved) then begin ErrorCode:=GetLastError; raise Exception.Create(Format('HttpQueryInfo Error %d Description %s',[ErrorCode,GetWinInetError(ErrorCode)])); end; if Result=200 then //read the body response in case which the status code is 200 if InternetQueryDataAvailable(hRequest, lpdwNumberOfBytesAvailable, 0, 0) then begin GetMem(lpvBuffer,lpdwBufferLength); try SetLength(Response,lpdwNumberOfBytesAvailable); InternetReadFile(hRequest, @Response[1], lpdwNumberOfBytesAvailable, dwBytesRead); finally FreeMem(lpvBuffer); end; end else begin ErrorCode:=GetLastError; raise Exception.Create(Format('InternetQueryDataAvailable Error %d Description %s',[ErrorCode,GetWinInetError(ErrorCode)])); end; finally InternetCloseHandle(hRequest); end; finally InternetCloseHandle(hConnect); end; finally InternetCloseHandle(hInet); end; end;  mX4 executed: 29/08/2022 11:15:20 Runtime: 0:0:1.952 Memload: 42% use  mX4 executed: 29/08/2022 11:15:33 Runtime: 0:0:1.803 Memload: 42% use  mX4 executed: 29/08/2022 11:21:34 Runtime: 0:0:1.771 Memload: 42% use  mX4 executed: 30/08/2022 14:01:29 Runtime: 0:0:2.477 Memload: 45% use  mX4 executed: 30/08/2022 15:43:22 Runtime: 0:0:2.406 Memload: 45% use  mX4 executed: 30/08/2022 16:07:02 Runtime: 0:0:2.369 Memload: 45% use  mX4 executed: 15/09/2022 09:48:03 Runtime: 0:0:2.790 Memload: 37% use  mX4 executed: 15/09/2022 22:28:52 Runtime: 0:0:7.33 Memload: 41% use  mX4 executed: 16/09/2022 14:03:40 Runtime: 0:0:7.696 Memload: 43% use