This is how I authenticate for using the Google API:
Private Function DoAuthentication(ByRef rStrToken As String, ByRef rParameters As OAuth2Parameters) As Boolean
Dim credential As UserCredential
Dim Secrets = New ClientSecrets() With {
.ClientId = m_strClientID,
.ClientSecret = m_strClientSecret
}
m_Scopes.Add(CalendarService.Scope.Calendar)
Try
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, m_Scopes,
"user", CancellationToken.None,
New FileDataStore("XXXXX.Application")).Result()
If credential.Token.IsExpired(Google.Apis.Util.SystemClock.Default) Then
credential.RefreshTokenAsync(CancellationToken.None)
End If
' Create the calendar service using an initializer instance
Dim initializer As New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "xxx"
}
m_Service = New CalendarService(initializer)
rStrToken = credential.Token.AccessToken.ToString()
rParameters.AccessToken = credential.Token.AccessToken
rParameters.RefreshToken = credential.Token.RefreshToken
Catch ex As Exception
' We encountered some kind of problem, perhaps they have not yet authenticated?
' Can we isolate that as the exception?
m_logger.Error(ex, "DoAuthentication")
Return False
End Try
Return True
End Function
And then in my Main
:
Dim parameters As New OAuth2Parameters
If (DoAuthentication(strToken, parameters)) Then
iResult = RESULT_SUCCESS_OAUTH
Else
Return RESULT_FAILED_OAUTH
End If
It then continues. The problem is that sometimes, even though the "authenticate" succeeds so that it starts to run the rest of the code. that I then get an exception:
2020-11-30 18:47:03.6762|ERROR|GoogleAuthandSync.Program|AddEventsToCalendarXML|System.IO.IOException: The process cannot access the file 'C:\Users\USERNAME\AppData\Roaming\XXXXX.Application\Google.Apis.Auth.OAuth2.Responses.TokenResponse-user' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
How can I authenticate / refresh the token and make sure we are ready to proceed so that this exception stops? It doesn't always happen.
(I renamed the token file for security in the code / error text above).
Should I be using the Await
keyword?
If credential.Token.IsExpired(Google.Apis.Util.SystemClock.Default) Then
Await credential.RefreshTokenAsync(CancellationToken.None)
End If
Would that make a difference? I notice that in this sample code they use await
.
I was encouraged to ask about the issue on GitHub (see discussion).
Turns out that I did not need to be using RefreshTokenAsync
in the way that I was. I was able to simplify my code and turn it into an Async
method liek this:
Private Async Function DoAuthenticationAsync() As Task(Of Boolean)
Dim credential As UserCredential
Dim Secrets = New ClientSecrets() With {
.ClientId = m_strClientID,
.ClientSecret = m_strClientSecret
}
Try
credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, m_Scopes,
"user", CancellationToken.None,
New FileDataStore("XXXXX.Application"))
' Create the calendar service using an initializer instance
Dim initializer As New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "XXXXX"
}
m_Service = New CalendarService(initializer)
Catch ex As Exception
' We encountered some kind of problem, perhaps they have not yet authenticated?
' Can we isolate that as the exception?
m_logger.Error(ex, "DoAuthentication")
Return False
End Try
Return True
End Function
Then, I had to move all of my code that was in the Main
function into a task:
Private Async Function Run() As Task(Of Integer)
...
End Function
Finally, I adjusted Main
like this:
Public Function Main() As Integer
Return RunAsync.Result
End Function
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments