I'm writing a script with Inno Setup that call my Web API written in C# that returns
File(bytes, "text/plain", "MyFileName.txt");
I read that ResponseText returns a limited number of chars if is called in synchronous way.
I'm using this code and I receive limited number of chars.
function ActivateLicense(): Boolean;
var
WinHttpReq: Variant;
jsonbody: String;
FStatus: Integer;
Stream: TFileStream;
Buffer: string;
Size: LongInt;
begin
try
WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
WinHttpReq.Open('POST', 'http://myweburl', False);
WinHttpReq.SetRequestHeader('Content-Type', 'application/json');
jsonbody := '{"ActivationCode":"' + KeyPage.Values[0] + '"}';
WinHttpReq.Send(jsonbody)
FStatus := WinHttpReq.Status; // 200=OK!
Result := FStatus=200;
if Result then
begin
Stream := TFileStream.Create(WizardDirValue() + '\license\mylicense.txt', fmCreate);
try
Size := WinHttpReq.GetResponseHeader('Content-Length');
Stream.WriteBuffer(WinHttpReq.ResponseText, Size);
finally
Stream.Free;
end;
end
else
begin
Log('HTTP Error: ' + IntToStr(WinHttpReq.Status) + ' ' +
WinHttpReq.StatusText);
MsgBox(WinHttpReq.ResponseText, mbError, MB_OK);
Result := False;
end;
except
MsgBox('Something went wrong trying to connect to our servers.', mbError, MB_OK);
Result := False;
end;
end;
Can I read ResponseText in async way? Or how can I use the others properties (ResponseBody, ResponseStream) of WinHttp.WinHttpRequest.5.1 to get all content?
[ActionName("activate")]
[HttpPost]
public async Task<IActionResult> Activate([FromBody] ActivateLicenseCommand command)
{
try
{
DirectoryInfo d = new DirectoryInfo(_environment.ContentRootPath + @"/licenses/");
FileInfo[] files = d.GetFiles("*.lic"); //Getting the files
if (files.Length != 1)
{
return Problem("There is an error with license's file. Please contact support.");
}
//Download the file
using (FileStream fsSource = new FileStream(files[0].FullName,
FileMode.Open, FileAccess.Read))
{
// Read the source file into a byte array.
byte[] bytes = new byte[fsSource.Length];
int numBytesToRead = (int)fsSource.Length;
int numBytesRead = 0;
while (numBytesToRead > 0)
{
// Read may return anything from 0 to numBytesToRead.
int n = fsSource.Read(bytes, numBytesRead, numBytesToRead);
// Break when the end of the file is reached.
if (n == 0)
break;
numBytesRead += n;
numBytesToRead -= n;
}
numBytesToRead = bytes.Length;
return File(bytes, "text/plain", files[0].Name);
}
}
catch (FileNotFoundException ioEx)
{
return Problem(ioEx.Message);
}
}
The content of the file that I want to send is:
<License>
<Id>0445e5a4-932a-491b-a59d-e017d8eddc1d</Id>
<Type>Standard</Type>
<Expiration>Mon, 21 Nov 2022 13:50:13 GMT</Expiration>
<Quantity>1</Quantity>
<LicenseAttributes>
<Attribute name="generated">2022-10-21 12:50:13Z</Attribute>
<Attribute name="license">2022-11-21 13:50:13Z</Attribute>
<Attribute name="updates">2022-11-21 13:50:13Z</Attribute>
<Attribute name="enableBetaVersions">0</Attribute>
</LicenseAttributes>
<Customer>
<Name>Pippo Pluto</Name>
<Email>[email protected]</Email>
</Customer>
<Signature>MIGHAkEoiobRz2rFP7Jh8jnIdbGA4mCLbyW9TEpf8VfHkPbXP3lFFi7NlS3K5SKsIPvIk90LdvnCyWTLKduMMwCevuflVQJCAIInvKBiPG4pD0vGZcO/am6vPkl5UDSamxRy49EmeMr0Yb7o6Xqm4oqGS+FuY8hET2oYEZw793o53XLiV1DXaD3W</Signature>
</License>
In Inno Script if I read ResponseText I don't receive the last character (>). If I call the Web API from C# method I can read all the content of the file.
For example with :
byte[] fileContent = await response.Content.ReadAsByteArrayAsync();
Imo, your problem is not about reading the response from the server. I think it's the saving the response to the file that is wrong.
Instead of the
WriteBuffer, try mySaveStringToUTF8FileWithoutBOMfunction fromCreate a UTF8 file without BOM with Inno Setup (Unicode version)
Side note: I believe most of your
Activatemethod implementation can be reduced toNo need for all that complicated and inefficient code to load whole file to memory only to return it from the method.