Accessing video framerate from WMP (10+) control in VB6 - vb6

I have to use the noted combination of tools, so suggestions that amount to "don't do that" are not helpful (-:
I can find no reliable way to determine the framerate of a video loaded into a WMP control. Is there some known way to get this value? It's such a basic piece of info that I can't believe I'm not missing something.
In theory I can instance IWMPMedia3 and set that to [player].currentmedia then ask for .GetAttributeByType("framerate", "", 0), but apparently there is some state that the player/media must be in for that to work, and I can't determine when that state exists.
In the IDE, when I try to get the attribute it always fails with Invalid procedure call or argument. I open the debug window and test whether the correct objects are instantiated -- they are. Then I can continue and I have the correct framerate. Clearly that won't work in production. (-:
It's not just waiting that does the trick -- I must actually debug test for Nothing on the objects to get it to proceed.

It appears the framerate item does not get initialized immediately after you set a source video to the control. I tried to wait and call DoEvents and at first found no reliable way to get it working. Displaying a message box and waiting 30 seconds sometimes did it, but not always.
I then decided to examine the attribute by code, and to my surprise, simply checking using getAttributeCountByType() seems to initialize the item without waiting a single millisecond.
In the following code, if the checkbox is enabled, which calls getAttributeCountByType(), the function always succeeds. I tried with AVI, MPEG and MP4 files and it worked on Windows 7. If the checkbox is not checked, it always fails with all types of video files:
WindowsMediaPlayer1.URL = Text1.Text
Dim media As IWMPMedia3
Set media = WindowsMediaPlayer1.currentMedia
If Check1.Value = vbChecked Then
Label1.Caption = "media.getAttributeCountByType " & media.getAttributeCountByType("framerate", "")
End If
MsgBox "Frame Rate = " & media.getItemInfoByType("framerate", "", 0)

Related

Ignore errors in UFT without generating a warning

On certain pages in my tests I have are-you-sure-popups that my or may not show up.
I solve this obvious problem using
On Error Resume Next
[Click OK]
This works fine but for all the popups that have actually not been present but it generates a warning which does look unnecessarily alarming. Is there any way to suppress these warning in UFT?
On Error Resume Next
Reporter.Filter = rfDisableAll
Dialog("TITLE").Button("LABEL").Click
Reporter.Filter = rfEnableAll
On Error GoTo 0
This is the Hacky Way.
For a very pure implementation you should be deterministic: always be in control, always know, what will happen and use the Exist Property on the Object if it's optional.
For Random Events the UFT Solution is Recovery Scenarios - but I did not see many implementations for it.

Debugging Step Into, Over, Out within VB6 IDE closes the class window

I am experiencing very strange behavior within VB6 IDE whenever the break point hits(Step Into, Out, Over), the class is closed and makes it impossible to debug. Then within window-Cascade i can re-open the class but again when break point hits, the class is closed. Can anyone help please.
Step execution does sometimes behave that way. The reason is that VB is event driven and when an event occurs, then the code behind that event will run, and your code that you are stepping through might NOT be the code that gets run, so things change and code runs while your PAUSED code is still on hold.
When I encounter that I overcome it by using debug.print to send my monitored variables' current values to the OUTPUT window, or if you need more elaborate capability, write a sub that sends the data to a local text file and then invoke that sub as needed, passing into the variables ( and labels ) that you want displayed.
Once debug.print or a logging routine is in place then run the code WITHOUT pauses or breaks. The debugging output will tell you what is happening, in what order etc, so no need to stop the code or risk altering the order of execution.
Be sure to include lots of 'context' data such as : 'Entering SUB_XYZ, Param values are A, B, C... NOW at line 99 in SUB XYZ.... NOW in TRUE side of IF TEST # 1....
Include time stamps on all outputs.
Put your tracing logic only around the suspected problem area, expand from there only as needed.
It's a pain, but it works.
I finally resolved this issue and problem was within Display settings within windows 10. Basically if I apply vertical settings by placing both screen vertically 2nd on top of first then this issue happens,if i apply horizontal settings then this issue does not happen.
problematic settings with vb
settings that does solves debugging issue. VB is so weird and old cannot cope with display settings

automatically logging in to SAP as part of a VBscript

I am working in SAP (PR2) and I have a large report that usually takes a long time (2 or more hours) to run. I have to take the output of this report and drop it into Excel to be manipulated and cleansed before bringing it into Access.
The ideal result would be a script that could launch automatically around 4am, login in to SAP, run the report, and have the results waiting for me when I come in. In short, I am missing parts 1 and 2, the automatic launch and automatic login to SAP.
I have pulled together a script that will start the report and then output the results as I want. The downside of this is that I don't get the results until about noon-ish each day, and that interrupts the workflow of those whom I support.
I have tried to run the necessary report in the background as suggested in other questions, but due to the size of the report and my limited access inside of SAP, it comes out in a way that is completely useless to me.
Thanks in advance for your help. Also, thanks for the help ya'll have given on prior questions :)
PS:As a bonus, if anyone knows how to encrypt a VBscript, that would be helpful as well.
Use the windows task scheduler to set a run daily at time task.
VBS cannot be encrypted but can be encoded. This will only stop the casual person fiddling with the code, decoding scripts are available online for anyone who really wants to get your code.
'ENCODE VBS TO VBE
Set oFilesToEncode = WScript.Arguments
Set oEncoder = CreateObject("Scripting.Encoder")
For i = 0 To oFilesToEncode.Count - 1
file = oFilesToEncode(i)
Set oFile = fso.GetFile(file)
Set oStream = oFile.OpenAsTextStream(1)
sSourceFile = oStream.ReadAll
oStream.Close
sDest = Encoder.EncodeScriptFile(".vbs",sSourceFile,0,"")
sFileOut = Left(file, Len(file) - 3) & "vbe"
Set oEncFile = fso.CreateTextFile(sFileOut)
oEncFile.Write sDest
oEncFile.Close
Next
WScript.quit
I use a software 'exescript' to convert to exe. Seems to work OK for me...

HTA - VBScript - Install program but wait for installation to complete

If you could give my a hand that would be great?
I have a HTA file nothing to fancy its to install a few programs one by one
I have been reading in a few places on how to wait for installation to complete
then install the next program but none make sense to me for what i want, also
they are saying to use wscript.sleep that would be great but it doesnt work in a HTA right ?
I have firefox, utorrent, symantec antivirus, adobe reader, office 2003 (packaged with KEY already)
and a few others.
i want to find switches to install silently but thats not important if this code someone is willing to show me works...
I hope I make sense ?
If you can help me it would be great ?
Cheers Pavle.
You might find something useful in my answer (https://stackoverflow.com/a/3742182/128427) to this question: How to get an HTA to restart itself?
It uses a VBScript helper to wait for a process to end (the HTA itself) then restarts the HTA. You could modify the vbscript instead to wait for a specific process to end (one of your installers), then return control to the HTA which starts the next installer and calls the wait script again.
I don't think an HTA can call the WScript.Sleep routine, but there are the setTimeout and setInterval methods in HTA that call a routine after X seconds, or repeatedly call a routine after every X seconds until cancelled. You can use these to check periodically if a process is still running (using WMI Win32_Process as I show in my other answer).
To process a list of items like this, instead of using a loop to go through a list and pause after each item, you have a central state-machine routine that calls itself every so often to advance the system.
'!! extremely "pseudo" pseudo-code follows
sub StartSystem()
state = "next program"
list = list of programs to install
AdvanceSystem()
end sub
sub AdvanceSystem()
if state = "next program"
if more items in list
start next installer
remove from list (or increment an index)
set state to "check program"
else
set state to "done"
if state = "check program"
use WMI to see if process is still running
if no
state = "next program"
if state <> "done"
setInterval(AdvanceSystem, 5000) ' call again in 5 seconds
end sub
' then somewhere in your HTA interface have a button to start things off
buttonClick = StartSystem()
Using an arrangement like this you may not even need to run a separate VBScript to check the process and sleep. Also, with this kind of incremental process, you can send output to a DIV somewhere so the user can see progress, whereas when processing things in a loop, output doesn't show up until the whole process has finished. After each pass through AdvanceSystem, the control returns to the HTA level and the system can update itself.
Let me know if you need a more specific example, I'll try to write something up.

Spin Down Hard Disk Programmatically on Windows?

How do you request Windows to spin down a hard disk programmatically? Is there any user-mode function I can call (or kernel-mode function to call or IRP to send) in order to make this happen?
I've tried making a program to send an ATA STANDBY command directly to the hard disk, but the problem is that this method doesn't inform the system, and hence whenever the system needs to flush the cache, it'll wake up the hard disk again. How do I tell the system to do this for me? (If the system does it, it'll save up the cache and "burst" the data when it gets too large, instead of writing in small increments.)
(The entire point here is to do this directly, not by changing the system-wide spin-down timeout to a 1-second period and waiting for the disk to spin down. I need a function I can call at a specific moment in time when I'm using my laptop, not something generic that doesn't suit 95% of situations.)
How far I've gotten so far:
I have a feeling that PoCallDriver and IRP_MJ_POWER might be useful for this, but I have very limited kernel-mode programming experience (and pretty much zero driver experience) so I really have no idea.
Please read:
Update:
People seem to be repeatedly mentioning the solutions that I have already mentioned do not work. Like I said above, I've already tried "hacky" solutions that change the timeout value or that directly issue the drive a command, and the entire reason I've asked this question here is that those did not do what I needed. Please read the entire question (especially paragraphs 2 and 3) before repeating what I've already said inside your answers -- that's the entire difficulty in the question.
More info:
I've found this document about Disk Idle Detection to be useful, but my answer isn't in there. It states that the Power Manager sends an IRP to the disk driver (hence why I suspect IRP_MJ_POWER to be useful), but I have no idea how to use the information.
I hope this helps:
This: http://msdn.microsoft.com/en-us/library/aa394173%28VS.85%29.aspx
Leads to this:
http://msdn.microsoft.com/en-us/library/aa394132%28VS.85%29.aspx#properties
Then, you can browse to this:
http://msdn.microsoft.com/en-us/library/aa393485(v=VS.85).aspx
This documentation seems to outline what you are looking for I think.
P.S. Just trying to help, don't shoot the messanger.
Have you tried WMI? Based on MSDN documentation, you should be able to send spindown command to HDD via WMI:
http://msdn.microsoft.com/en-us/library/aa393493%28v=VS.85%29.aspx
uint32 SetPowerState(
[in] uint16 PowerState,
[in] datetime Time
);
EDIT:
This code lists all drives in system and drives that support this API:
strServer = "."
Set objWMI = GetObject("winmgmts://" & strServer & "/root\cimv2")
rem Set objInstances = objWMI.InstancesOf("CIM_DiskDrive",48)
Set objInstances = objWMI.ExecQuery("Select * from CIM_DiskDrive",,48)
On Error Resume Next
For Each objInstance in objInstances
With objInstance
WScript.Echo Join(.Capabilities, ", ")
WScript.Echo Join(.CapabilityDescriptions, ", ")
WScript.Echo .Caption
WScript.Echo .PNPDeviceID
WScript.Echo "PowerManagementCapabilities: " & .PowerManagementCapabilities
WScript.Echo "PowerManagement Supported: " & .PowerManagementSupported
WScript.Echo .Status
WScript.Echo .StatusInfo
End With
On Error Goto 0
Next
Just save this code as a .vbs file and run that from command line.
I do not have an answer to the specific question that Mehrdad asked.
However, to help others who find this page when trying to figure out how to get their disk to standby when it should but doesn't:
I found that on a USB disk, MS PwrTest claims that the disk is off, but actually it is still spinning. This occurs even with really short global disk timeouts in win 7. (This implies that even if the system thinks it has turned the disk off, it might not actually be off. Consequently, Mehrdad's original goal might not work even if the correct way to do it is found. This may relate to how various USB disk controllers implement power state.)
I also found that the program HDDScan successfully can turn off the disk, and can successfully set a timeout value that the disk honors. Also, the disk spins up when it is accessed by the OS, a good thing if you need to use it, but not so good if you are worrying about it spinning up all the time to flush 1kB buffers. (I chose to set the idle timeout in HDDScan to 1 minute more than the system power manager timeout. This hopefully assures that the system will not think the disk is spun up when it is not.)
I note that powercfg has an option to prevent the idle clock from restarting from small infrequent disk writes. (Called "burst ignore time.")
You can get HDDScan here: HDDScan.com and PwrTest here: Windows Driver Kit. Unfortunately, the PwrTest thing forces you to have a lot of other MS stuff installed first, but it is all free if you can figure out how to download it from their confusing web pages.
While there is no apparent way to do what you're asking for (i.e. tell power management "act as if the timer for spinning down the disk has expired"), there may be a couple ways to simulate it:
Call FlushFileBuffers on the drive (you need to be elevated to open \\.\C), then issue the STANDBY command to the drive.
Make the API call that sets the timeout for spinning down the disk to 1 second, then increase it back to its former value after 1 second. Note that you may need to ramp up to the former value rather than immediately jump to it.
I believe the Devcon Command line utility should be able to accomplish what you need to do. If it does - the source code is available in the Windows Ddk.

Resources