I have found a function which invokes Microsoft.DirectX.AudioVideoPlayback to get the length of a video file.
Here is that code:
`Private Function GetVideoInformation(ByVal videoFilePath As String) As VideoInfo
Try
If My.Computer.FileSystem.FileExists(videoFilePath) Then
Dim videoToGetInfoOn As Microsoft.DirectX.AudioVideoPlayback.Video
videoToGetInfoOn = New Microsoft.DirectX.AudioVideoPlayback.Video(videoFilePath)
Dim atpf As Double = videoToGetInfoOn.AverageTimePerFrame
Dim vidSize As New Size
vidSize = videoToGetInfoOn.Size
Dim thisVideoInfo As New VideoInfo
thisVideoInfo.videoWidth = vidSize.Width
thisVideoInfo.videoHeight = vidSize.Height
thisVideoInfo.videoDuration = videoToGetInfoOn.Duration
If videoToGetInfoOn.Duration > 0 Then
defaultLength = videoToGetInfoOn.Duration
End If
If atpf > 0 Then
thisVideoInfo.videoFps = 1 / atpf
Else
thisVideoInfo.videoFps = 0
End If
Return thisVideoInfo
Else
Throw New Exception("Video File Not Found" & vbCrLf & vbCrLf & videoFilePath)
Return Nothing
End If
Catch ex as Exception
msgbox(ex.message)
End Try
End Function`
I have a timer that calls this function once on 2 seconds to check many videos, and the app works fine for the first 10 videos or so. After that, it throws
"Error in application"
message instead.
In general, things from DirectShow/DirectX MUST be disposed of in the way the docs require or this sort of thing happens. Here, you are creating videoToGetInfoOn objects but never releasing them.
You need to explicitly release all the resources you and it allocated with videoToGetInfoOn = Nothing before your procedure exits. Try that.
I will add that MediaInfo.DLL can be used to get everything from a media file without the overhead of Dx. There is a commandline version that you might be able to read from reading stdout.
I got it working.
The code needs a dispose method.
Here is the final code:
`Private Function GetVideoInformation(ByVal videoFilePath As String) As VideoInfo
Try
If My.Computer.FileSystem.FileExists(videoFilePath) Then
Dim videoToGetInfoOn As Microsoft.DirectX.AudioVideoPlayback.Video
videoToGetInfoOn = New Microsoft.DirectX.AudioVideoPlayback.Video(videoFilePath)
Dim atpf As Double = videoToGetInfoOn.AverageTimePerFrame
Dim vidSize As New Size
vidSize = videoToGetInfoOn.Size
Dim thisVideoInfo As New VideoInfo
thisVideoInfo.videoWidth = vidSize.Width
thisVideoInfo.videoHeight = vidSize.Height
thisVideoInfo.videoDuration = videoToGetInfoOn.Duration
If videoToGetInfoOn.Duration > 0 Then
defaultLength = videoToGetInfoOn.Duration
End If
If atpf > 0 Then
thisVideoInfo.videoFps = 1 / atpf
Else
thisVideoInfo.videoFps = 0
End If
videoToGetInfoOn.Dispose() 'this line here needed to be added
Return thisVideoInfo
Else
Throw New Exception("Video File Not Found" & vbCrLf & vbCrLf & videoFilePath)
Return Nothing
End If
Catch ex as Exception
msgbox(ex.message)
End Try
End Function`
Related
This topic is related to Loop through links and download PDF's
I am trying to convert my current VBA code into VBScript. I have already understood that I have to remove the variable types (As ... part of Dim statements) and use CreatObject to get those objects but otherwise everything should port as-is. DoEvents will also have to be replaced with something like Wscript.sleep.
I came up with some problems. Currently while running VBS file I am getting an error saying "Object required: 'MSHTML'". Pointing to line 65, where I have Set hDoc = MSHTML.HTMLDocument. I have tried to search on Google but got nothing helpful for this one.
How I should proceed with this one?
DownloadFiles("https://www.nordicwater.com/products/waste-water/")
Sub DownloadFiles(p_sURL)
Set xHttp = CreateObject("Microsoft.XMLHTTP")
Dim xHttp
Dim hDoc
Dim Anchors
Dim Anchor
Dim sPath
Dim wholeURL
Dim internet
Dim internetdata
Dim internetlink
Dim internetinnerlink
Dim arrLinks
Dim sLink
Dim iLinkCount
Dim iCounter
Dim sLinks
Set internet = CreateObject("InternetExplorer.Application")
internet.Visible = False
internet.navigate (p_sURL)
Do Until internet.ReadyState = 4
Wscript.Sleep 100
Loop
Set internetdata = internet.document
Set internetlink = internetdata.getElementsByTagName("a")
i = 1
For Each internetinnerlink In internetlink
If Left(internetinnerlink, 36) = "https://www.nordicwater.com/product/" Then
If sLinks <> "" Then sLinks = sLinks & vbCrLf
sLinks = sLinks & internetinnerlink.href
i = i + 1
Else
End If
Next
wholeURL = "https://www.nordicwater.com/"
sPath = "C:\temp\"
arrLinks = Split(sLinks, vbCrLf)
iLinkCount = UBound(arrLinks) + 1
For iCounter = 1 To iLinkCount
sLink = arrLinks(iCounter - 1)
'Get the directory listing
xHttp.Open "GET", sLink
xHttp.send
'Wait for the page to load
Do Until xHttp.ReadyState = 4
Wscript.Sleep 100
Loop
'Put the page in an HTML document
Set hDoc = MSHTML.HTMLDocument
hDoc.body.innerHTML = xHttp.responseText
'Loop through the hyperlinks on the directory listing
Set Anchors = hDoc.getElementsByTagName("a")
For Each Anchor In Anchors
'test the pathname to see if it matches your pattern
If Anchor.pathname Like "*.pdf" Then
xHttp.Open "GET", wholeURL & Anchor.pathname, False
xHttp.send
With CreateObject("Adodb.Stream")
.Type = 1
.Open
.write xHttp.responseBody
.SaveToFile sPath & getName(wholeURL & Anchor.pathname), 2 '//overwrite
End With
End If
Next
Next
End Sub
Function:
Function getName(pf)
getName = Split(pf, "/")(UBound(Split(pf, "/")))
End Function
Instead of Set hDoc = MSHTML.HTMLDocument, use:
Set hDoc = CreateObject("htmlfile")
In VBA/VB6 you can specify variable and object types but not with VBScript. You have to use CreateObject (or GetObject: GetObject function) to instantiate objects like MSHTML.HTMLDocument, Microsoft.XMLHTTP, InternetExplorer.Application, etc instead of declaring those using Dim objIE As InternetExplorer.Application for example.
Another change:
If Anchor.pathname Like "*.pdf" Then
can be written using StrComp function:
If StrComp(Right(Anchor.pathname, 4), ".pdf", vbTextCompare) = 0 Then
or using InStr function:
If InStr(Anchor.pathname, ".pdf") > 0 Then
Also, at the beginning of your sub, you do the following:
Set xHttp = CreateObject("Microsoft.XMLHTTP")
Dim xHttp
You should declare your variables before assigning them values or objects. In VBScript this is very relaxed, your code will work because VBScript will create undefined variables for you but it's good practice to Dim your variables before using them.
Except for Wscript.sleep commands, your VBScript code will work in VB6/VBA so you can debug your script in VB6 or VBA apps (like Excel).
Try
If Not MyCache.GetInstance.AzureCacheOn Then
reader = New IO.StreamReader(FilePathUtility.GetInstance.MapPath(objUrl))
Else
request = System.Net.HttpWebRequest.Create(objUrl)
response = DirectCast(request.GetResponse, System.Net.HttpWebResponse)
strm = DirectCast(response.GetResponseStream, IO.Stream)
reader = New IO.StreamReader(strm)
End If
Dim list = New List(Of String)()
Using reader
Dim line As String
While (InlineAssignHelper(line, reader.ReadLine())) IsNot Nothing
list.Add(line)
End While
End Using
lines = list.ToArray()
Catch ex As Exception
Throw ex
End Try
Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
target = value
Return value
End Function
I have this code snippet which is working fine but now in csv file i need to add some information in first line so i need to skip the first line how I can do that please help screenshot of csv is attached
You can simply use ReadLine once before you start processing the lines:
Using reader
reader.ReadLine())
Dim line As String
While (InlineAssignHelper(line, reader.ReadLine())) IsNot Nothing
list.Add(line)
End While
End Using
Call read line before while, also check if the line is not blank and then only go to loop.
This will skip your first line.
Code something like :
Using reader
Dim line As String
// if reader.ReadLine() is not empty
While (InlineAssignHelper(line, reader.ReadLine())) IsNot Nothing
list.Add(line)
End While
// end if
End Using
To skip nth line (2nd in your case) use :
Using reader
Dim line As String
// count = 0, n = 1 // 0 = first line, 1 = 2nd line etc
While (InlineAssignHelper(line, reader.ReadLine())) IsNot Nothing
// if(count++ != n)
list.Add(line)
// end if
End While
End Using
I am trying to run Office365 cmdlets in a vb.net webservice project.The code is:
Public Function ExcutePowershellCommands() As ObjectModel.Collection(Of PSObject)
Try
Dim userList As ObjectModel.Collection(Of PSObject) = Nothing
Dim initialSession As InitialSessionState = InitialSessionState.CreateDefault()
initialSession.ImportPSModule(New String() {"MSOnline"})
Dim O365Password_secureString As New System.Security.SecureString()
Dim O365Password As String = "password"
For Each x As Char In O365Password
O365Password_secureString.AppendChar(x)
Next
Dim credential As New PSCredential("username", O365Password_secureString)
Dim connectCommand As New Command("Connect-MsolService")
connectCommand.Parameters.Add((New CommandParameter("Credential", credential)))
Dim getCommand As New Command("Get-MsolUser")
Using psRunSpace As Runspace = RunspaceFactory.CreateRunspace(initialSession)
psRunSpace.Open()
For Each com As Command In New Command() {connectCommand, getCommand}
Dim pipe As Pipeline = psRunSpace.CreatePipeline()
pipe.Commands.Add(com)
Dim results As ObjectModel.Collection(Of PSObject) = pipe.Invoke()
Dim [error] As ObjectModel.Collection(Of Object) = pipe.[Error].ReadToEnd()
If [error].Count > 0 AndAlso com.Equals(connectCommand) Then
Throw New ApplicationException("Problem in login! " + [error](0).ToString())
Return Nothing
End If
If [error].Count > 0 AndAlso com.Equals(getCommand) Then
Throw New ApplicationException("Problem in getting data! " + [error](0).ToString())
Return Nothing
Else
userList = results
End If
Next
psRunSpace.Close()
End Using
Return userList
Catch generatedExceptionName As Exception
Throw
End Try
End Function
When Connect-MsolService is run, I get this error message:
There was no endpoint listening at https://provisioningapi.microsoftonline.com/provisioningwebservice.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
I can run this function successfully within a windows App. I think some thing might be wrong in IIS. any idea?
My Project Contain call to SetSession ManyTime SomeTime it's Crashing. Please any one can help me.
Here section code:
public Function SetSession(sSessionName As String) As Boolean
Dim intCount As Integer
'Call Refresh
SetSession = False
Dim oSessions As ExtaSessions = Nothing
Dim oSession As ExtraSession = Nothing
moSession = Nothing
oSessions=TryCast(moSystem.Sessions,ExtraSessions)
moSession=TryCast(oSessions.Item(sSessionName),ExtraSession)'=> Crashing in this line
If Information.Err().Number <> 0 Then
For intcount = 1 To oSessions.Count
oSession = TryCast(oSessions.Item(intCount), ExtraSession)
if oSession.Name = sSessionName then
moSession = oSession
Exit for
End if
NExt
End if
if moSession is Nothing then
Exit Function End If
SetSession = True
End Function
In following attachment PrintScreen for Exception
Finnaly I fix my problem
before change:
Dim oSessions As ExtaSessions = Nothing
Dim oSession As ExtraSession = Nothing
moSession = Nothing
oSessions=TryCast(moSystem.Sessions,ExtraSessions)
moSession=TryCast(oSessions.Item(sSessionName),ExtraSession)
after change:
Dim oSessions As EXTRA.ExtraSessions
Dim oSession As EXTRA.ExtraSession
moSession = Nothing
moSystem = New Extra.ExtraSystem
Try
oSessions = DirectCast(moSystem.Sessions,EXTRA.ExtraSessions)
moSession = DirectCast(oSessions.Item(sSessionName),EXTRA.ExtraSession)
Catch ex As Exception
Interaction.MsgBox(ex)
End Try
I just Init moSystem to Extra.ExtraSystem
and i changed ExtaSessions to EXTRA.ExtraSessions
and DirectCast to trycast and it's work 100%
thx :)
I am using ZipOutputStream to get files from db, compress to zip and download (zip file around 400mb).
During this, my app pool memory is going up to 1.4gb and after download is complete, its coming down to 1gb when it should come back to like 100 mb or something.
There are only like 10 users using this app and only 1 user using this particular page.
i am calling the dispose method. I aslo tried explictly calling GC.Collect but still no use.
Am i missing anything here?
Thanks in advance.
Dim zipStream = New ZipOutputStream(HttpContext.Current.Response.OutputStream)
Try
da.Fill(ds)
For Each dr As DataRow In ds.Tables(0).Rows
Try
Dim docName As String = ""
strImgID = dr("image_id")
If Not IsDBNull(dr("loan_number")) Then iLoanID = dr("loan_number")
If Not IsDBNull(dr("document_name")) Then docName = dr("document_name")
Dim ext As String = dr("image_type_extension")
Dim strFinalFileName As String = ""
strFinalFileName = docName & "_" & iLoanID & ext
Dim b As Byte() = dr("image_binary")
Dim fileEntry = New ZipEntry(Path.GetFileName(strFinalFileName))
zipStream.PutNextEntry(fileEntry)
zipStream.Write(b, 0, b.Length)
Catch ex As Exception
LogError(ex, iLoanID & "," & strImgID)
AddError(sb, ex, iLoanID & "," & strImgID)
End Try
Next
Catch ex As Exception
Throw
Finally
zipStream.Close()
zipStream.Dispose()
cmd.Connection.Close()
cmd.Connection.Dispose()
End Try
You need to chunk data into the stream rather than allocate all at once.
E.g. (in c#)
byte[] buffer = new byte[4096];
FileStream readFs = File.OpenRead(strFile);
for (int rnt = readFs.Read(buffer, 0, buffer.Length);
rnt > 0;
rnt = readFs.Read(buffer, 0, buffer.Length))
{
zipoutputstream.Write(buffer, 0, rnt);
}
I think this will help with your memory issue. Please comment back if not..