Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous HTTP POST request without waiting for response in Inno Setup

Tags:

I have an Inno Setup Installer and need to make an API call during setup. This posts some data to a remote API.

The POST call is performed in the [Code] section using Pascal and the WinHttpRequest object. The API is ASP.Net WebAPI 2 (C#).

I have full control of all parts of the process, i.e. the Inno Setup script, it's Code section and the WebAPI.

Problem

I can make POST call synchronously without any issue, but if I set the async flag to true on the WinHttpRequest.Open() method, the .Send() method does not seem to execute at all.


procedure PostData(postural: String);
   var 
     WinHttpReq: Variant;
     ReqContent: String;
   begin
     try
       WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
       ReqContent := 'item=value';
       WinHttpReq.Open('POST', postUrl, true);
       WinHttpReq.SetRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
       WinHttpReq.Send(ReqContent);
     except
     end;
   end;

I checked with a breakpoint in the VisualStudio Debugger, and the endpoint never gets called.

While searching here and on Google I only found various attempts for getting the response asynchronously, but I could not find a solution for this issue. I do not need the response, this is a fire-and-forget kind of API call.


Condensed Question

Why does the API not receive the call and how can I fix this?

Thanks.

like image 516
metalar Avatar asked Jun 14 '17 10:06

metalar


1 Answers

For the asynchronous request to complete, the instance of WinHttpRequest has to stay "alive".

For that you have to make sure at least that:

  • The variable WinHttpReq survives until the request completes. I.e. in your particular case, you cannot leave PostData before the request completes. Or you need to make the WinHttpReq a global variable (not local to PostData procedure).

      var 
        WinHttpReq: Variant;
    
      procedure PostData(postural: String);
      var 
        ReqContent: String;
      begin
        try
          WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
          ReqContent := 'item=value';
          WinHttpReq.Open('POST', postUrl, true);
          WinHttpReq.SetRequestHeader(
            'Content-Type', 'application/x-www-form-urlencoded');
          WinHttpReq.Send(ReqContent);
        except
        end;
      end;
    
  • The process (installer) itself runs until the request completes.

like image 103
Martin Prikryl Avatar answered Oct 01 '22 02:10

Martin Prikryl