Example using WinHTTP API to read out web page's code [Windows only]

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Example using WinHTTP API to read out web page's code [Windows only]

Post by UEZ »

This is an example to use Windows WinHTTP API to read out a web page code and extract program version to check for an update.

You need libpcre.a otherwise it will fail.

Compile it with -s console

Code: Select all

'Ported from WinHTTP.au3 by trancexx to FB by UEZ
'v0.1 build 2021-01-05 beta

#Include Once "windows.bi"

'libpcre.a needed in lib folder! Download link here: https://www.freebasic.net/forum/viewtopic.php?f=17&t=19095&start=495#p278794
#Ifdef __Fb_64bit__
	#Libpath "lib\win64\"
#Else
	#Libpath "lib\win32\"
#Endif
#Define PCRE_STATIC
#Include "pcre.bi"

'https://www.pcre.org/original/doc/html/index.html
Function StringRegEx(sPattern As String, sString As String, aArr() As String, iOptions as Ulong = 0, bDebug As Boolean = False) As Long
	Const iStrVecCnt = 300

	Dim As Zstring Ptr pErrorStr, pSubStrMatchStr
	Dim As Long iRegexExec, iErrOffset, aStrVec(iStrVecCnt - 1), iResult = -1, i, j = 0, k = 1
	Dim As pcre_extra tRegexStudy
	Dim As pcre Ptr pRegexCompiled
	Dim As pcre_extra Ptr pRegexStudy

'	OPTIONS (second argument) (||'ed together) can be:
'	PCRE_ANCHORED       -- Like adding ^ at start of pattern.
'	PCRE_CASELESS       -- Like m//i
'	PCRE_DOLLAR_ENDONLY -- Make $ match end of string regardless of \n's
'						  No Perl equivalent.
'	PCRE_DOTALL         -- Makes . match newlins too.  Like m//s
'	PCRE_EXTENDED       -- Like m//x
'	PCRE_EXTRA          -- 
'	PCRE_MULTILINE      -- Like m//m
'	PCRE_UNGREEDY       -- Set quantifiers to be ungreedy.  Individual quantifiers
'						  may be set to be greedy if they are followed by "?".
'	PCRE_UTF8           -- Work with UTF8 strings.
	
	'first, the regex string must be compiled
	pRegexCompiled = pcre_compile(sPattern, iOptions, @pErrorStr,  Cast(Long Ptr, @iErrOffset), 0)
	If pRegexCompiled = NULL Then
		Return iResult
	End If
	
	'optimize the regex
	'pcre_study() returns NULL for both errors and when it can not optimize the regex.
	'The last argument is how one checks for errors (it is NULL if everything works, and points to an error string otherwise.
	pRegexStudy = pcre_study(pRegexCompiled, 0, @pErrorStr)
	If pRegexStudy = NULL Then
		Return iResult - 1
	End If

	Redim aArr(0 To iStrVecCnt)
	
	Do 
		iRegexExec = pcre_exec(pRegexCompiled, pRegexStudy, Strptr(sString), Len(sString), j, 0, Cast(Long Ptr, @aStrVec(0)), iStrVecCnt)
		If iRegexExec > 0 Then
			For i = 0 To iRegexExec - 1
				pcre_get_substring(Strptr(sString), @aStrVec(0), iRegexExec, i, @pSubStrMatchStr)
				If k > Ubound(aArr) Then Redim Preserve aArr(0 To (Ubound(aArr) Shl 1))
				aArr(k) = pSubStrMatchStr[0]
				'? aStrVec(i * 2), aStrVec(i * 2 + 1), pSubStrMatchStr
				k += 1
			Next
			j = aStrVec(1)
		Else
			If bDebug Then	
				Select Case iRegexExec
					Case PCRE_ERROR_NOMATCH
						? "String did not match the pattern"
					Case PCRE_ERROR_NULL
						? "Something was null"
					Case PCRE_ERROR_BADOPTION
						? "A bad option was passed"
					Case PCRE_ERROR_BADMAGIC
						? "Magic number bad (compiled re corrupt?)"
					Case PCRE_ERROR_UNKNOWN_NODE
						? "Something kooky in the compiled re"
					Case PCRE_ERROR_NOMEMORY
						? "Ran out of memory"
					Case Else
						? "Unknown error"
				End Select
			Endif
		Endif
		pcre_free_substring(Cast(Zstring Ptr, @pSubStrMatchStr))
	Loop Until iRegexExec < 1

	Redim Preserve aArr(0 To k - 1)
	
	pcre_free(pRegexCompiled)
	#Ifdef PCRE_CONFIG_JIT
		pcre_free_study(pRegexStudy)
	#Else
		pcre_free(pRegexStudy)
	#Endif
	pcre_free(pRegexCompiled)
	
	aArr(0) = Str(k - 1)

	Return 1
End Function

Type HINTERNET As LPVOID

Const CRLF = Chr(10, 13), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0, WINHTTP_ACCESS_TYPE_NO_PROXY = 1, WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3, WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY = 4, WINHTTP_FLAG_ESCAPE_DISABLE = &h00000040, INTERNET_DEFAULT_HTTPS_PORT = 443, INTERNET_DEFAULT_HTTP_PORT = 80, INTERNET_DEFAULT_PORT = 0, WINHTTP_NO_PROXY_NAME = "", WINHTTP_NO_PROXY_BYPASS = "", WINHTTP_NO_REFERER = "", WINHTTP_DEFAULT_ACCEPT_TYPES = 0, WINHTTP_FLAG_SECURE = &h00800000, WINHTTP_NO_ADDITIONAL_HEADERS = "", WINHTTP_NO_REQUEST_DATA = ""

Dim Shared As Any Ptr __hWinHTTPLib = 0
Dim Shared WinHttpOpen As Function(sUserAgent As LPCWSTR, iAccessType As Long, sProxyName As LPCWSTR, sProxyBypass As LPCWSTR, iFlag As Long) As HINTERNET
Dim Shared WinHttpCloseHandle As Function(__hWinHTTPLib As Any Ptr) As Boolean
Dim Shared WinHttpConnect As Function(hSession As HINTERNET, sServerName As LPCWSTR, iServerPort As Long, Reserved As DWORD) As HINTERNET
Dim Shared WinHttpOpenRequest As Function(hConnect As HINTERNET, sVerb As LPCWSTR, sObjectName As LPCWSTR, sVersion As LPCWSTR, sReferrer As LPCWSTR, pAcceptTypes As Any Ptr, iFlags As Long) As HINTERNET
Dim Shared WinHttpSendRequest As Function(hInternet As HINTERNET, sHeader As LPCWSTR, iHeadersLength As Long, pOptionalBuff As HINTERNET, iOptionalLength As Long, iTotalLength As Long, pContext As DWORD_PTR) As Boolean
Dim Shared WinHttpReceiveResponse As Function(hInternet As HINTERNET, iReserved As LPVOID) As Boolean
Dim Shared WinHttpReadData As Function(hRequest As HINTERNET, pBuffer As LPVOID, iNumberOfBytesToRead As Long, pNumberOfBytesRead As LPDWORD) As Boolean
Dim Shared WinHttpQueryDataAvailable As Function(hRequest As HINTERNET, pNumberOfBytesAvailable As LPDWORD) As Boolean

Function _WinHttpStartup() As Boolean
	__hWinHTTPLib = Dylibload("Winhttp.dll")
	If __hWinHTTPLib = 0 Then Return False
	WinHttpOpen = Dylibsymbol(__hWinHTTPLib, "WinHttpOpen")
	WinHttpCloseHandle = Dylibsymbol(__hWinHTTPLib, "WinHttpCloseHandle")
	WinHttpConnect = Dylibsymbol(__hWinHTTPLib, "WinHttpConnect")
	WinHttpOpenRequest = Dylibsymbol(__hWinHTTPLib, "WinHttpOpenRequest")
	WinHttpSendRequest = Dylibsymbol(__hWinHTTPLib, "WinHttpSendRequest")
	WinHttpReceiveResponse = Dylibsymbol(__hWinHTTPLib, "WinHttpReceiveResponse")
	WinHttpReadData = Dylibsymbol(__hWinHTTPLib, "WinHttpReadData")
	WinHttpQueryDataAvailable = Dylibsymbol(__hWinHTTPLib, "WinHttpQueryDataAvailable")
	Return True
End Function

Function _WinHttpShutdown() As Boolean
	If __hWinHTTPLib Then 
		Dylibfree(__hWinHTTPLib)
		Return True
	Endif
	Return False
End Function

Function _WinHttpOpen(sUserAgent As String = "FB_WinHHTP/1.0", iAccessType As Long = WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, sProxyName As String = WINHTTP_NO_PROXY_NAME, sProxyBypass As String = WINHTTP_NO_PROXY_BYPASS, iFlag As Long = 0) As HINTERNET
	If __hWinHTTPLib = 0 Then Return 0
	Return WinHttpOpen(Wstr(sUserAgent), iAccessType, Wstr(sProxyName), Wstr(sProxyBypass), iFlag)
End Function

Function _WinHttpCloseHandle(__hInternet As Any Ptr = __hWinHTTPLib) As Boolean
	If __hInternet = 0 Then Return False
	Return WinHttpCloseHandle(__hInternet)
End Function

Function _WinHttpConnect(hSession As HINTERNET, sServerName As String, iServerPort As Long = INTERNET_DEFAULT_PORT) As HINTERNET
	If hSession = 0 Then Return 0
	Return WinHttpConnect(hSession, Wstr(sServerName), iServerPort, 0)	
End Function

Function _WinHttpOpenRequest(hConnect As HINTERNET, sVerb As String = "GET", sObjectName As String = "", sVersion As String = "HTTP/1.1", sReferrer As String = WINHTTP_NO_REFERER, pAcceptTypes As Any Ptr = WINHTTP_DEFAULT_ACCEPT_TYPES, iFlags As Long = WINHTTP_FLAG_ESCAPE_DISABLE) As HINTERNET
	If hConnect = 0 Then Return 0
	Return WinHttpOpenRequest(hConnect, Wstr(Ucase(sVerb)), Wstr(sObjectName), Wstr(Ucase(sVersion)), Wstr(sReferrer), pAcceptTypes, iFlags)
End Function

Function _WinHttpQueryDataAvailable(hRequest As HINTERNET, Byref pNumberOfBytesAvailable As LPDWORD = NULL) As Ulong
	If hRequest = 0 Then Return 0
	Return WinHttpQueryDataAvailable(hRequest, pNumberOfBytesAvailable)
End Function

Function _WinHttpReadData(hRequest As HINTERNET, iMode As Ubyte = 0, iNumberOfBytesToRead As Uinteger = 8192, pBuffer As LPDWORD = 0) As String
	If hRequest = 0 Then Return ""
	Dim As Ulong iNumberOfBytesRead = 0, i
	Dim As Ubyte aBuffer(iNumberOfBytesToRead)
	WinHttpReadData(hRequest, @aBuffer(0), iNumberOfBytesToRead, @iNumberOfBytesRead)
	If iNumberOfBytesRead = 0 Then Return ""
	Dim As String sHTML
	For i = 0 To iNumberOfBytesRead
		sHTML &= Chr(aBuffer(i))
	Next
	Return sHTML
End Function

Function _WinHttpReceiveResponse(hRequest As HINTERNET) As Boolean
	If hRequest = 0 Then Return False
	Return WinHttpReceiveResponse(hRequest, 0)
End Function

Function _WinHttpSendRequest(hRequest As HINTERNET, sHeaders As String = WINHTTP_NO_ADDITIONAL_HEADERS, sOptional As String = WINHTTP_NO_REQUEST_DATA, iTotalLength As Ulong = 0, iContext As ULong = 0) As Boolean
	If hRequest = 0 Then Return False
	Dim As Ulong iOptionalLength = Len(sOptional), i
	Dim As Ubyte aOptional(Len(sOptional) - 1)
	If iOptionalLength > 0 Then
		For i = 0 To iOptionalLength - 1
			aOptional(i) = Asc(Mid(sOptional, i + 1, 1))
		Next
	End If
	If iTotalLength = 0 Or iTotalLength < iOptionalLength Then iTotalLength += iOptionalLength
	Return WinHttpSendRequest(hRequest, Wstr(sHeaders), 0, @aOptional(0), iOptionalLength, iTotalLength, iContext)
End Function

Function _WinHttpSimpleReadData(hRequest As HINTERNET, iMode As Ubyte = 0) As String
	If hRequest = 0 Then Return ""
	If iMode > 2 Then iMode = 2
	If _WinHttpQueryDataAvailable(hRequest) > 0 Then
		Dim As String sData, d
		Select Case iMode
			Case 0
				Do
					d = _WinHttpReadData(hRequest, 0)
					If d = "" Then Exit Do
					sData &= d
				Loop Until False
				Return sData
		End Select
	End If
End Function

Function _WinHttpSimpleSendRequest(hConnect As HINTERNET, sPath As String = "", sType As String = "GET", sReferrer As String = WINHTTP_NO_REFERER, sData As String = WINHTTP_NO_REQUEST_DATA, sHeader As String = WINHTTP_NO_ADDITIONAL_HEADERS) As HINTERNET
	If hConnect = 0 Then Return 0
	Dim As HINTERNET hRequest = _WinHttpOpenRequest(hConnect, sType, sPath, "HTTP/1.1", sReferrer)
	If hRequest = 0 Then Return 0
	If sType = Ucase("POST") And sHeader = WINHTTP_NO_ADDITIONAL_HEADERS Then sHeader = "Content-Type: application/x-www-form-urlencoded" & CRLF
	If _WinHttpSendRequest(hRequest, sHeader, sData) = False Then Return 0
	If _WinHttpReceiveResponse(hRequest) = False Then Return 0
	Return hRequest
End Function

Dim As Any Ptr hSession, hConnect, hRequest
Dim As String sRead
Dim As String aResult()

If _WinHttpStartup() = False Then End

hSession = _WinHttpOpen()
hConnect = _WinHttpConnect(hSession, "forum.qbasic.at")
hRequest = _WinHttpSimpleSendRequest(hConnect, "viewtopic.php?t=8996")

sRead = _WinHttpSimpleReadData(hRequest)
StringRegEx("<title>.*Color Constants v(\d*\.\d+)\h*\[", sRead, aResult())

If aResult(0) = "2" Then ? "Online Color Constants version is v" & aResult(2)

_WinHttpCloseHandle(hRequest)
_WinHttpCloseHandle(hConnect)
_WinHttpCloseHandle(hSession)
_WinHttpShutdown()
Sleep
It will extract code from the page https://forum.qbasic.at/viewtopic.php?t=8996 to get the version number in the title using RegEx which is "Color Constants v0.75 [nur Windows]"

The output should be: Online Color Constants version is v0.75
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by dodicat »

Thanks UEZ, I got this to work.
I note that the German site page is unicode only.
I had to fiddle about a bit to get a title by this method:

Code: Select all

#include "file.bi"

dim as string g
g += "Const TriStateTrue = -1 ' forUnicode support"+chr(10) 
g += "URL = InputBox(""Enter (or paste) the URL to extract the Code ""&vbcr&vbcr&_"+chr(10)
g += """Exemple """"https://www.freebasic.net"""""",""Extraction of Source text and html  "",""https://www.freebasic.net/forum/index.php"")"+chr(10)
g += "If URL = """" Then WScript.Quit"+chr(10)
g += "Titre = ""Extraction du Code Source de "" & URL"+chr(10)
g += "Set ie = CreateObject(""InternetExplorer.Application"")"+chr(10)
g += "Set objFSO = CreateObject(""Scripting.FileSystemObject"")"+chr(10)
g += "ie.Navigate(URL)"+chr(10)
g += "ie.Visible=false"+chr(10)
g += "DO WHILE ie.busy"+chr(10)
g += "LOOP"+chr(10)
g += "DataHTML = ie.document.documentElement.innerHTML"+chr(10)
g += "DataTxt = ie.document.documentElement.innerText"+chr(10)
g += "strFileHTML = ""CodeSourceHTML.txt"""+chr(10)
g += "strFileTxt = ""CodeSourceTxt.txt"""+chr(10)
g += "Set objHTMLFile = objFSO.OpenTextFile(strFileHTML,2,True, TriStateTrue)"+chr(10)
g += "objHTMLFile.WriteLine(DataHTML)"+chr(10)
g += "objHTMLFile.Close"+chr(10)
g += "Set objTxtFile = objFSO.OpenTextFile(strFileTxt,2,True, TriStateTrue)"+chr(10)
g += "objTxtFile.WriteLine(DataTxt)"+chr(10)
g += "objTxtFile.Close"+chr(10)
g += "ie.Quit"+chr(10)
g += "Set ie=Nothing"+chr(10)
g += " Ouvrir(strFileHTML)"+chr(10)
g += " Ouvrir(strFileTxt)"+chr(10)
g += "wscript.Quit"+chr(10)
g += "Function Ouvrir(File)"+chr(10)
g += "    Set ws=CreateObject(""wscript.shell"")"+chr(10)
g += "    ws.run ""Notepad.exe ""& File,1,False"+chr(10)
g += "end Function"+chr(10)


Sub string_split(byval s As String,chars As String,result() As String)
    redim result(0)
    Dim As String var1,var2
Dim As long pst,LC=len(chars)
      #macro split(stri)
    pst=Instr(stri,chars)
    var1="":var2=""
    If pst<>0 Then
    var1=Mid(stri,1,pst-1)
    var2=Mid(stri,pst+LC)
    Else
    var1=stri
End if
    if len(var1) then 
    redim preserve result(1 to ubound(result)+1)
    result(ubound(result))=var1
    end if
    #endmacro
   Do
   split(s):s=var2
Loop Until var2=""
End Sub

function savefile(filename As String,p As String) as string
    Dim As long n=freefile
    If Open (filename For Binary Access Write As #n)=0 Then
        Put #n,,p
        Close
    Else
        Print "Unable to save " + filename:sleep:end
    End If
    return filename
End function

Function loadfile(file as string) as String
	If FileExists(file)=0 Then Print file;" not found":Sleep:end
   dim as long  f=freefile
    Open file For Binary Access Read As #f
    Dim As String text
    If Lof(f) > 0 Then
      text = String(Lof(f), 0)
      Get #f, , text
    End If
    Close #f
    return text
end Function

Function _Remove(Byval Text As String,Char As String) As String
    Var index = 0,asci=Asc(char)
    For i As Integer = 0 To Len(Text) - 1
        If Text[i] <> ASCi Then Text[index] = Text[i] : index =index+ 1
    Next 
    Return Left(Text,index)
End Function

Sub runscript(filename As String) 
  Shell "cscript.exe /Nologo "+ filename 
End Sub


savefile("script.vbs",g)
runscript("script.vbs")
kill "script.vbs"
var L=loadfile("codesourcehtml.txt")
redim as string result()
string_split(L,chr(10),result())
'output the title to the console
print "Page title if available:"
dim as string s=chr(0)+"<"+chr(0)+"t"+chr(0)+"i"+chr(0)+"t"+chr(0)+"l"+chr(0)+"e"+chr(0)+">"+chr(0)
dim as string s2=chr(0)+"<"+chr(0)+"/"+chr(0)+"t"+chr(0)+"i"+chr(0)+"t"+chr(0)+"l"+chr(0)+"e"+chr(0)+">"+chr(0)
dim as string t
for n as long=lbound(result) to ubound(result)
if instr(result(n),s) then t=_remove( rtrim(ltrim(result(n),s),s2),chr(0)):print t
next n


sleep
 
(You also get the page source code in html and text)
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by Josep Roca »

If I may, an example using my WinFBX framework:

Code: Select all

'#CONSOLE ON
#include once "Afx/CWinHttpRequest.inc"
using Afx

' // Create an instance of the CWinHttp class
DIM pWHttp AS CWinHttpRequest

' // Open an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://forum.qbasic.at/viewtopic.php?t=8996"

' // Send an HTTP request to the HTTP server
pWHttp.Send

' // Wait for response with a timeout of 5 seconds
DIM iSucceeded AS LONG = pWHttp.WaitForResponse(5)

IF iSucceeded THEN
   ' // Get the response headers
   DIM cbsResponseText AS CBSTR = pWHttp.GetResponseText
   ' // Extract the version number from the Color Constants title
   DIM cbs AS CBSTR = AfxStrExtract(1, cbsResponseText, "Color Constants v", " [")
   print "Online Color Constants version is v" & cbs
END IF

PRINT
PRINT "Press any key..."
SLEEP
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by jj2007 »

José, your code yields just "Online Color Constants version is v", for some reason. With the snippet below (using Extract$), I get "0.75", which seems more correct.

Code: Select all

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Inkey Extract$(FileRead$("https://forum.qbasic.at/viewtopic.php?t=8996"), "Color Constants v", "[", xsExcL or xsExcR)
EndOfCode
@dodicat:
- "cscript.exe" is not recognised...
- codesourcehtml.txt not found

@UEZ: FB64 is ok, Gas and gcc version 8.1. give me undefined reference to `pcre_free_study' (I do have ...FreeBasic\lib\pcre-844-static\win32\libpcre.a)
Last edited by jj2007 on Jan 07, 2021 15:27, edited 1 time in total.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by Josep Roca »

It works correctly using the WinFBE editor and the files that come with it. I don't know how you have compilet it.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by jj2007 »

Josep Roca wrote:It works correctly using the WinFBE editor and the files that come with it. I don't know how you have compilet it.
I compiled it with standard GAS, i.e. -t 2000 -s console. Now I tried again, and it works, so the error seems to be on my side - apologies.

P.S., it gets weird:

Code: Select all

' // Wait for response with a timeout of 5 seconds
DIM iSucceeded AS LONG = pWHttp.WaitForResponse(5)

IF iSucceeded THEN
   ' // Get the response headers
   DIM cbsResponseText AS CBSTR = pWHttp.GetResponseText
   ' // Extract the version number from the Color Constants title
   DIM cbs AS CBSTR = AfxStrExtract(1, cbsResponseText, "Color Constants v", " [")
   print "Online Color Constants version is v" & cbs
else
	print "not succeeded"
END IF
The code compiles and runs but gives me
a) "not succeeded" when run via the editor and its batch file,
b) "Online Color Constants version is v0.75" when run directly from M$ Explorer
Mysteries of Windows...
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by Josep Roca »

You can change the value in WaitForResponse if needed. -1 is infinite time-out.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by dodicat »

jj2007 wrote:José, your code yields just "Online Color Constants version is v", for some reason. With the snippet below (using Extract$), I get "0.75", which seems more correct.

Code: Select all

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Inkey Extract$(FileRead$("https://forum.qbasic.at/viewtopic.php?t=8996"), "Color Constants v", "[", xsExcL or xsExcR)
EndOfCode
@dodicat:
- "cscript.exe" is not recognised...
- codesourcehtml.txt not found

@UEZ: FB64 is ok, Gas and gcc version 8.1. give me undefined reference to `pcre_free_study' (I do have ...FreeBasic\lib\pcre-844-static\win32\libpcre.a)
Hi jj2007
cscript.exe is the command line Windows Scripting Host which runs script files..

Code: Select all

Usage: CScript scriptname.extension [option...] [arguments...]

Options:
 //B         Batch mode: Suppresses script errors and prompts from displaying
 //D         Enable Active Debugging
 //E:engine  Use engine for executing script
 //H:CScript Changes the default script host to CScript.exe
 //H:WScript Changes the default script host to WScript.exe (default)
 //I         Interactive mode (default, opposite of //B)
 //Job:xxxx  Execute a WSF job
 //Logo      Display logo (default)
 //Nologo    Prevent logo display: No banner will be shown at execution time
 //S         Save current command line options for this user
 //T:nn      Time out in seconds:  Maximum time a script is permitted to run
 //X         Execute script in debugger
 //U         Use Unicode for redirected I/O from the console  
I thought all windows had it, I am win 10 64 bits.
The windows version is wscript.exe

Code: Select all


Shell "wscript.exe" 
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by jj2007 »

dodicat wrote:Shell "wscript.exe"
I am on Win7-64. It suddenly works when I use the full path, i.e. C:\Windows\System32\cscript.exe. However, the next hurdle is this: script.vbs(6, 1) (null): Invalid signature
Josep Roca wrote:You can change the value in WaitForResponse if needed. -1 is infinite time-out.
Same effect. It apparently depends on the location of the exe, or on the fact that it was launched via CreateProcess/batch file instead of via Explorer; no idea...
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by dodicat »

Do you use the web page from UEZ?
https://forum.qbasic.at/viewtopic.php?t=8996
Just copy and paste the address into the box and click OK
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by UEZ »

@dodicat: thank you for your contribution which would be the last approach I would think of to use vbs. :-)
My intention was to read out the version number from the title to check if it's current.
Btw, you don't need VBS to access InternetExplorer.Application COM object. You can use also disphelper.bi. For example I used it to access MS Word.
Josep Roca wrote:If I may, an example using my WinFBX framework
yes, for sure. I'm always open for different approaches.
Your version works properly. It provides the version number. Hmm, it seems that I have reinvented the wheel again... ^^
Your access code to WinHTTP API is different than what I did. Learned something new today. :-)
jj2007 wrote:@UEZ: FB64 is ok, Gas and gcc version 8.1. give me undefined reference to `pcre_free_study' (I do have ...FreeBasic\lib\pcre-844-static\win32\libpcre.a)
I've tested it only with the current version of FB (x86 / x64) and not the complete toolchain. Thx for testing.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by jj2007 »

dodicat wrote:Do you use the web page from UEZ?
https://forum.qbasic.at/viewtopic.php?t=8996
Yes, of course. The "invalid signature" must be an internal problem of my machine's configuration. However, my WinInet version works fine.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by dodicat »

Hi UEZ.
Do you have a 64 bit disphelper??
I use the 32 bit version now and then.
I note that powershell can extract info, but it cannot accept & in the string.
However your link is free of ampersands.
Probably powershell has yet to evolve some.

Code: Select all


Function pipeout(Byval s As String="") Byref As String
    Var f=Freefile
    Dim As String tmp
    Open Pipe s For Input As #f 
    s=""
    Do Until Eof(f)
        Line Input #f,tmp
        s+=tmp+Chr(10)
    Loop
    Close #f
    Return s
End Function 

function getpage(page as string,fields as string=".content")as string
return pipeout( "powershell "+"(Invoke-WebRequest "+page+ ")"+fields)
end function

var s= getpage("https://forum.qbasic.at/viewtopic.php?t=8996")
var i1=instr(s,"<title>")
var i2=instr(s,"</title>")
print
print mid(s,i1+7,(i2-i1)-7)

 s= getpage("https://forum.qbasic.at/viewtopic.php?t=8996",".headers")
print "Page headers:"
print s


sleep 
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by UEZ »

dodicat wrote:Do you have a 64 bit disphelper??
Try this link: libdisphelper_x64.zip
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Example using WinHTTP API to read out web page's code [Windows only]

Post by dodicat »

Thanks UEZ.
This is approximately it with disphelper.

Code: Select all

#define UNICODE
#include "windows.bi"
#include once "disphelper/disphelper.bi"
type Chars
    FBChars as IDispatch ptr
    declare function Text() as string
    end type
type doc
    FBdoc as IDispatch ptr
    declare function TextLines() as Chars
    end type
type IE
    FBIE as IDispatch Ptr
    declare function MainDoc() as doc
    declare function FindPage(as string) as string
    declare function Show () byref as integer
    declare sub Start()
    declare constructor()
    declare destructor()
end type

constructor IE
Start
this.Show = true
end constructor

destructor IE
dhcallmethod( FBIE ,"quit")
end destructor


sub IE.Start()
    dhInitialize(TRUE)
    dhToggleExceptions(FALSE)
    dhCreateObject("InternetExplorer.Application",NULL,@FBIE)
end sub

function IE.Show() byref as integer static
      dim as integer I
      dhPutValue(FBIE,".Visible = %b", @I)
    return I
end function

function IE.FindPage(S as string) as string
      while len(this.MainDoc.TextLines.Text)=0
    dhcallmethod(FBIE,".Navigate %s",S)
    sleep 500
    wend
    return this.MainDoc.TextLines.Text
end function

function IE.MainDoc() as doc
    dim temp as doc
        dhGetValue("%o",@temp.FBdoc,FBIE,"Document")
    return temp
end function

function doc.TextLines() as Chars
    dim temp as Chars
        dhGetValue("%o",@temp.FBChars,FBdoc,"Body")
    return temp
end function

function Chars.Text() as string
    Dim temp As Zstring Ptr
        dhGetValue("%s",@temp,FBChars,"innerHTML")
    return *temp
end function

Sub _split(byval s As String,_chars As String,result() As String)
    redim result(0)
    Dim As String var1,var2
Dim As long pst,LC=len(_chars)
      #macro split(stri)
    pst=Instr(stri,_chars)
    var1="":var2=""
    If pst<>0 Then
    var1=Mid(stri,1,pst-1)
    var2=Mid(stri,pst+LC)
    Else
    var1=stri
End if
    if len(var1) then 
    redim preserve result(1 to ubound(result)+1)
    result(ubound(result))=var1
    end if
    #endmacro
   Do
   split(s):s=var2
Loop Until var2=""
End Sub



dim as IE mypage
redim as string s()
var ans= mypage.FindPage("https://forum.qbasic.at/viewtopic.php?t=8996")
_split(ans,chr(10),s())
for n as long=lbound(s) to ubound(s)
      if instr(s(n),"maintitle") then
           print mid(s(n),instr(s(n),"highlight"))
            end if
      next
      

sleep

  
Post Reply