I would like to use a visual basic desktop app to upload a file to Google Drive. The main purpose of the app does much more, but this is a time-saving feature I need to add
I have downloaded the NuGet for Google.Apis.Drive.v2 and have added the following code:
Imports Google.Apis.Auth.OAuth2
Imports Google.Apis.Drive.v2
Imports Google.Apis.Drive.v2.Data
Imports Google.Apis.Services
I have a button to call my code:
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
CreateService()
UploadFile(myFile)
End Sub
And then I have code to Create the Service and Upload the File:
Private Sub CreateService()
Dim ClientId = "My ClientID copied from Google"
Dim ClientSecret = "My Client Secret"
Dim MyUserCredential As UserCredential = _
GoogleWebAuthorizationBroker.AuthorizeAsync(New ClientSecrets() _
With {.ClientId = ClientId, .ClientSecret = ClientSecret}, _
{DriveService.Scope.Drive}, "user", CancellationToken.None).Result
Service = New DriveService(New BaseClientService.Initializer() _
With {.HttpClientInitializer = MyUserCredential, .ApplicationName = "SiteVisitTool"})
End Sub
Private Sub UploadFile(FilePath As String)
Me.Cursor = Cursors.WaitCursor
If Service.ApplicationName <> "SiteVisitTool" Then CreateService()
Dim TheFile As New Google.Apis.Drive.v2.Data.File
TheFile.Title = "Deliverables"
TheFile.Description = "Site Visit data for Google forms"
TheFile.MimeType = "text/csv"
Dim ByteArray As Byte() = System.IO.File.ReadAllBytes(FilePath)
Dim Stream As New System.IO.MemoryStream(ByteArray)
Dim UploadRequest As FilesResource.InsertMediaUpload = Service.Files.Insert(TheFile, Stream, TheFile.MimeType)
Me.Cursor = Cursors.Default
MsgBox("Upload Finished")
End Sub
The code runs and I get the message box that the upload has finished. I have checked Drive and the file doesn't exist. Sometimes I'm prompted for the account I want to use and then I have to activate it, but I always get the message that it as uploaded. Highly frustrated!
"SiteVisitTool" is the Project name on Google.
Should this just be going to the Root folder of Drive?
Also, if we can get this worked out, I'd like to follow-up and save it to a specific folder.
This turned out to be a simple fix. Apparently the website I got this solution from was missing the upload line. So after you create your Upload request, you need to tell it to upload.
Dim UploadRequest As FilesResource.InsertMediaUpload = Service.Files.Insert(TheFile, Stream, TheFile.MimeType)
UploadRequest.Upload()
As for specifying a folder to upload it to, I added where I set the properties of TheFile:
TheFile.Parents = New List(Of ParentReference)() From {
New ParentReference() With {
.Id = sFolderID
}
}
Related
I did a small development where it is necessary to connect to a SharePoint list, the development works well with my user, but when testing with another user who has the same privileges on the site, it sends the following error message
"The sign-in name or password does not match one in the Microsoft Account System. "
I already tried with other users that the site are owners, but I get the same result.
Can you help me see what is the error in the above?
This is my code.
Imports Microsoft.SharePoint.Client
Imports Microsoft.SharePoint
Imports System.Security
Imports System.Net
Public Class Form4
Dim siteUrl As String = "https://example.sharepoint.com/site/SiteExample/"
Dim context As New ClientContext(siteUrl)
Dim web As Web
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
Dim userNameSP As String = TextBox1.Text
Dim password As String = TextBox2.Text
Dim secureString As SecureString = New NetworkCredential("", password).SecurePassword
Dim cred = New SharePointOnlineCredentials(userNameSP, secureString)
Dim clientContext As New ClientContext(siteUrl)
clientContext.Credentials = cred
Dim web As Web = clientContext.Web
Dim oWebsite As Web = clientContext.Web
Dim collList As ListCollection = oWebsite.Lists
Dim oList As List = collList.GetByTitle("Example Test")
clientContext.Load(oList)
clientContext.ExecuteQuery()
Dim query As CamlQuery = CamlQuery.CreateAllItemsQuery()
query.ViewXml = "<View Scope='RecursiveAll'><Query><ViewFields><FieldRef Name='Category/></ViewFields></Query></View>"
Dim AllItems As ListItemCollection = oList.GetItems(query)
clientContext.Load(AllItems)
clientContext.ExecuteQuery()
If AllItems.Count > 0 Then
... Do Something
end if
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
End Class
Thank you in advance.
Did the user account enable MFA Authentication ?
I tested the same code snippet with a normal user account without MFA, it's working as expected.
Please check MFA Status in this:
https://account.activedirectory.windowsazure.com/UserManagement/MultifactorVerification.aspx?BrandContextID=O365
If enabling the MFA, please disable it, as CSOM didn't support MFA currently.
This is the solution code to do log-in in a sharepoint.
Imports Microsoft.Office.Interop
Imports System.IO
Imports Microsoft.SharePoint.Client
Imports Microsoft.SharePoint
Imports System.Security
Imports System.Net
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim siteUrl As String = "https://example.sharepoint.com/sites/TRAINING/"
Dim authManager = New OfficeDevPnP.Core.AuthenticationManager()
Dim ctx As ClientContext = authManager.GetWebLoginClientContext(siteUrl)
Dim web As Web = ctx.Web
ctx.Load(web, Function(w) w.Title)
ctx.ExecuteQuery()
Console.WriteLine("You have connected to {0} site, with Multi Factor Authentication enabled!!", web.Title)
Try
Do Something...
Catch ex As Exception
MessageBox.Show("An error occurred:" & Environment.NewLine & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Sorry for the delay.
Regards.
I have created a login authentication using the Microsoft Graph API which means after I sign in, as a result, I have the access token of the current user signed-in. My next step is to create a Microsoft Teams Meeting on behalf of the current user signed-in.
I have tried to follow the Microsoft documentation Application POST onlinemeetings, where It shows the required steps to achieve this scenario.
Unfortunately, they didn't provide an example of how it can be achieved in VB.Net (which is not a big deal because I have converted the code to VB).
Currently, I am stuck on sending a POST request to generate this meeting based on the hard coded values when the user clicks on the button.
Please have a look at the code below:
Imports System.IO
Imports System.Net
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Threading.Tasks
Imports Microsoft.Graph
Imports Microsoft.IdentityModel.Clients.ActiveDirectory
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class _Default
Inherits Page
Private Shared httpClient As HttpClient = New HttpClient()
Private Shared context As AuthenticationContext = Nothing
Private Shared credential As ClientCredential = Nothing
Private Shared graphClient As GraphServiceClient
Private Shared authprovider As IAuthenticationProvider
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim code = HttpContext.Current.Request.QueryString("Code")
If Not Page.IsPostBack Then
If code <> "" Then
Dim url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
Dim myParameters = "grant_type=authorization_code&code=" & code & "&redirect_uri=https://localhost:4312/&client_id=CLIENTID&client_secret=CLIENTSECRET"
Dim wb = New WebClient
wb.Headers(HttpRequestHeader.ContentType) = "application/x-www-form-urlencoded"
Dim response = wb.UploadString(url, "POST", myParameters)
responseToken.Text = response
Success.Text = "O365 login successful. Below is the response token"
Dim SurroundingClass = JsonConvert.DeserializeObject(Of SurroundingClass)(response)
Dim rss As JObject = JObject.Parse(response)
Dim token = rss.SelectToken("access_token")
Dim res = GetUsers(token)
End If
End If
End Sub
Private Shared Async Function GetUsers(ByVal result As String) As Task(Of String)
Try
Dim users As String = Nothing
Dim querystring As String = "api-version=1.6"
Dim uri = "https://graph.microsoft.com/v1.0/me"
httpClient.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", result)
httpClient.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
Dim User = GetMeAsync().Result
Console.WriteLine($"Welcome {User.DisplayName}!\n")
Dim getResult = Await httpClient.GetAsync(uri)
If getResult.Content IsNot Nothing Then
users = Await getResult.Content.ReadAsStringAsync()
End If
Return users
Catch ex As Exception
Throw ex
End Try
End Function
Protected Sub tes_Click(sender As Object, e As EventArgs)
Try
'Dim fr As System.Net.HttpWebRequest
Dim client_id = ""// App Client ID'
Dim uri = "https://localhost:4312/"
Dim targetURI As String = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" & client_id &
"&redirect_uri=" & uri & "&response_type=code&scope=openid+Mail.Read"
Response.Redirect(targetURI)
Catch ex As System.Net.WebException
'Error in accessing the resource, handle it
End Try
End Sub
Public Shared Async Function CreateMeeting() As Task(Of OnlineMeeting)
Try
graphClient = New GraphServiceClient(authprovider)
Dim onlineMeeting = New OnlineMeeting With {
.StartDateTime = DateTimeOffset.Parse("2020-04-23T21:33:30.8546353+00:00"),
.EndDateTime = DateTimeOffset.Parse("2020-04-23T22:03:30.8566356+00:00"),
.Subject = "Application Token Meeting",
.Participants = New MeetingParticipants With {
.Organizer = New MeetingParticipantInfo With {
.Identity = New IdentitySet With {
.User = New Identity With {
.Id = "MYID"
}
}
}
}
}
Dim encodings As New UTF8Encoding
Dim serializer As New JavaScriptSerializer()
Dim arrayJson As String = serializer.Serialize(onlineMeeting)
Dim result As String = Nothing
Dim postRequest As HttpWebRequest = DirectCast(WebRequest.Create("https://graph.microsoft.com/v1.0/me/onlineMeetings"), HttpWebRequest)
postRequest.Method = "POST"
postRequest.ContentType = "application/json"
httpClient.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", Token)
If postRequest.Method = "POST" Then
Dim parsedContent As String = JsonConvert.SerializeObject(onlineMeeting)
Dim encoding As ASCIIEncoding = New ASCIIEncoding()
Dim bytes As Byte() = encoding.GetBytes(parsedContent)
Dim newStream As Stream = postRequest.GetRequestStream()
newStream.Write(bytes, 0, bytes.Length)
newStream.Close()
End If
Dim createMeetings = Await graphClient.Communications.OnlineMeetings.Request().AddAsync(onlineMeeting)
Console.WriteLine("The meeting has been created")
Return createMeetings
Catch ex As ServiceException
Console.WriteLine($"Error while creating the meeting: {ex.Message}")
Return Nothing
End Try
End Function
Public Sub InvokeMeeting(sender As Object, e As EventArgs)
Try
Dim testing = CreateMeeting()
Catch ex As Exception
End Try
End Sub
PS: I have added the permission required to call this API to be able to create a Teams meeting.
Any suggestions on how to achieve the following scenario?
Any help will be greatly appreciated.
Thank you!
I get this error:
Could not load file or assembly 'SendGrid.SmtpApi, Version=1.1.3.0, Culture=neutral, PublicKeyToken=55aa52d3c3c0d2b2' or one of its dependencies. The system cannot find the file specified.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Create the email object first, then add the properties.
Dim myMessage As SendGridMessage
myMessage = New SendGridMessage()
' Add the message properties.
myMessage.AddTo("example#gmail.com")
myMessage.From = New MailAddress("example#gmail.com")
myMessage.Subject = "Test Sendgrid"
' Add plain text body only:
myMessage.Text = "Body"
Dim username As String
Dim pswd As String
username = "username"
pswd = "password"
Dim credentials As NetworkCredential
credentials = New NetworkCredential(username, pswd)
' // Create an Web transport for sending email
Dim transportWeb As New Web(credentials)
transportWeb.DeliverAsync(myMessage)
End Sub
Screenshot:
https://i.imgur.com/b2iWa0L.png
Please help
Perhaps you could try:
Dim myMessage As SmtpApi.SendGridMessage
myMessage = New SmptApi.SendGridMessage()
I'm using this code:
Imports System.IO
Imports System.Net
Public Class sendftp
Public Function UploadFileToFtp(ByVal f As String, ByVal host As String, ByVal username As String, ByVal password As String, ByVal folderToUploadTo As String) As Boolean
Try
'create an FtpRequest object, holds the value of the path you are trying to reach
Dim ftpRequest As FtpWebRequest = DirectCast(FtpWebRequest.Create(New Uri(host & "/" & Path.GetFileName(folderToUploadTo))), FtpWebRequest)
'pass in our login credentials
ftpRequest.Credentials = New NetworkCredential(username, password)
'set the method to Upload, since we're uploading a file
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile
'don't use passive mode
ftpRequest.UsePassive = True
'unless we're uploading a file like an image
'we need to set this to false as we're not uploading
'binary data
ftpRequest.UseBinary = True
'set KeepAlive to false
ftpRequest.KeepAlive = False
'now create a new FileStream, then open the file we're uploading
'this allows us to get the size of the file for our buffer
Dim stream As FileStream = File.OpenRead(f)
'create a byte[] array buffer the size of the file
'we're uploading
Dim buffer As Byte() = New Byte(stream.Length - 1) {}
'read in our file into the FileStream
stream.Read(buffer, 0, buffer.Length)
'close the FileStream
stream.Close()
'create a new stream, this will be used to write to the
'FTP server
Dim requestStream As Stream = ftpRequest.GetRequestStream()
'write the data to the FTP server
requestStream.Write(buffer, 0, buffer.Length)
'close the stream
requestStream.Close()
'since we made it this far return true
Return True
Catch ex As Exception
'something went wront so let the user know
MessageBox.Show("Error uploading file: " + ex.Message, "Upload Error")
'return false
Return False
End Try
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
UploadFileToFtp("C:\file.txt", "ftp://ftp.drivehq.com", "**user**", "**password**", "new.txt")
End Sub
End Class
And it works.
However I would like to use my FileZilla Server, so I edit the ftp url:
UploadFileToFtp("C:\file.txt", "ftp://localhost", "**user**", "**password**", "new.txt")
but I get this error : ?
The remote server returned an error:(550) File unavailable (e.g., file not found, no access).
I can't figure it out, any ideas?
Turned out to be permission that I fixed by going to ftp server settings... sorry for my inconvenience
Public Function UploadCourseXML(ByVal fileStream As String, companyID As Integer, ByVal tokenID As String) As String Implements ICorePointService.UploadCourseXML
If (Not IsCustomerAuthentication(companyID, tokenID)) Then
Throw New Exception("Authentication failed. Please provider Company ID and Token ID")
End If
Dim doc As XDocument = XDocument.Parse(fileStream)
doc.Save("Update_XML")' error occures here... Access to the path c:\...etc. is denied
.. i want to save this in solution explorer
Return "result"
End Function
Refer this link :
http://support.microsoft.com/kb/301233
This for windows & web also
Imports System.IO
Imports System.Net
Imports System.Xml
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'To just download xml text
'Download text and save
Dim wc As New WebClient
Dim xmlText As String = wc.DownloadString("http://www.localcallingguide.com/xmllocalexch.php?exch=015800")
File.WriteAllText("new file path.xml", xmlText)
'Or
'To load stream directly into XML Document :
'Get data in stream
Dim webRequest As WebRequest = webRequest.Create("http://www.localcallingguide.com/xmllocalexch.php?exch=015800")
Dim webResponse As WebResponse = webRequest.GetResponse
Dim webStream As Stream = webResponse.GetResponseStream
'Optionally
'If you want you can read text from stream
'Dim reader As New StreamReader(webStream)
'reader.ReadToEnd 'will give same output as wc.downloadString()
'Load stream
Dim xmlDoc As New XmlDocument
xmlDoc.Load(webStream)
'select any level nodes using xpath
Dim Nodes As XmlNodeList = xmlDoc.SelectNodes("//lca-data/prefix/exch")
'iterate in selected nodes
For Each node As XmlNode In Nodes
RichTextBox1.AppendText(node.InnerText & vbCrLf)
Next
End Sub
End Class
You'll get a Access to the path '...' is denied error if the folder is flagged ReadOnly. You need to remove this flag prior to saving the file.
Dim info As DirectoryInfo = New DirectoryInfo("C:\folder1\folder2\folder3")
If (info.Exists AndAlso ((info.Attributes And FileAttributes.[ReadOnly]) = FileAttributes.[ReadOnly])) Then
info.Attributes = (info.Attributes Xor FileAttributes.[ReadOnly])
End If
If you're writing to an existing file, also make sure the file is not flagged ReadOnly. Just change DirectoryInfo to FileInfo.
Dim info As FileInfo = New FileInfo("C:\folder1\folder2\folder3\file.ext")
You may refer to the below given link to find out your problem,
http://support.microsoft.com/kb/2623670#method4