Suppress messages from embedded Windows Media PLayer - vb.net

I'm working on a Windows Form Application in which I have embedded a Windows Media Player that lets you play video files. The unique thing is that I have changed the extension of the media files (for reasons which I can't get into here). For instance, "xyz.wmv" might be called "xyz.ext". They play just fine, but before they play, I get the message:
"The file you are attempting to play has an extension that does not match the file format. Playing the file may result in unexpected behaviour. Do you want the Player to try to play the file?"
You can click yes and you can even check the box to not show that message again, but I don't want that for all the obvious reasons including the fact that it confuses users. I have looked into the .settings properties but I cannot find a way to suppress this message and more importantly other messages that might come up.

The .ext (for example) extension is not known to media player, hence the warning.
What you can do to change this is modify the registry and register this extension. This is described officially here: File Name Extension Registry Settings
The most simple way to do it is to create a registry key like this:
HKEY_CURRENT_USER\Software\Microsoft\MediaPlayer\Player\Extensions\.ext
And add two key values:
Runtime (DWORD): 6
Permissions (DWORD): 15 (or 0xF in hexa)
This is shown here:

NOTE: this answer was originally in response to a bounty question and edit which was removed on how to do this via code. Parts of this are still relevant to the original question.
You can do this pretty straight forward IF you have admin rights as you need to edit the registry. Not sure how far you will get without admin rights and can test later, but here is how to do this via code (in a real implementation I would do this as part of a setup - or check if the keys exist each time which seems wasteful):
You need to add one key (showing two here for registering the extensions, you may need additional keys for auto-play or a setting on the player):
private void Form1_Load(object sender, EventArgs e) {
/*This first key is not necessary - and if you will be using common
* extensions like mp4, skip this step altogether!!
*/
RegistryKey key = Registry.CurrentUser.OpenSubKey("Software", true)
.OpenSubKey("Classes", true);
key.CreateSubKey(".myExt");
key = key.OpenSubKey(".myExt", true);
key.SetValue("", "WMP11.AssocFile.myExt");
key.SetValue("Content Type", "video/x-ms-wmv");
key.SetValue("PerceivedType", "video");
/*Here is the magic key which will make the dialog go away*/
key = Registry.CurrentUser.OpenSubKey("Software", true)
.OpenSubKey("Microsoft", true)
.OpenSubKey("MediaPlayer", true)
.OpenSubKey("Player", true)
.OpenSubKey("Extensions", true);
key.CreateSubKey(".myExt");
key = key.OpenSubKey(".myExt", true);
key.SetValue("", "");
key.SetValue("Permissions", 0x20);
axWindowsMediaPlayer1.URL = #"C:\Users\Public\Documents\Wildlife.myExt";
}
Media Player creates other keys when you add through its dialog, but the only one definitely needed is: HKEY_Current_User.Software.Microsoft.MediaPlayer.Player.Extensions
If you want to see all the keys Media Player adds,
choose a crazy extension,
click always allow when prompted and then
search the registry for all the keys that get created.
The above code is tested and working for me - confirming the dialog before adding the keys and the lack of any dialog after.
This is a good generic process for programmatically adding file associations and default programs to the Windows Registry from .NET. You have to be careful about registering the extension (the first key I set above) IF the extension already exists (TEST FOR THIS). Otherwise the above code will happily overwrite your current values. All you really should need is the one added to: HKEY_Current_User.Software.Microsoft.MediaPlayer.Player.Extensions anyway. Think it through, check in advance, and test before you go crazy in the registry!!
It is also always a great idea to backup your registry before playing with it.
Final note: missed your question on how to reproduce once you have clicked always allow: just remove the entry in HKEY_Current_User.Software.Microsoft.MediaPlayer.Player.Extensions and voila!
This answer assumes you have a working knowledge of regedit.
Final note #2: Response geared to the questions in the Bounty. Other errors can be suppressed by setting telling Media Player to allow you to handle error events and then writing your custom handler. I have not done this before so cannot comment on the ease and what can/cannot be controlled through this method.
The Windows Media Player control does not raise an exception when it encounters an error such as an invalid URL. Instead, it signals an event. Your application should handle error events sent by the Player.
These can then be handled by creating / registering a MediaError event:
private void axWindowsMediaPlayer1_MediaError(object sender, AxWMPLib._WMPOCXEvents_MediaErrorEvent e) {
// Handle errors and profit!
}
Then set this as the handler in the Events property window for your control - same for other events such as ErrorEvent.

Related

Eclipse Editor: automatically switch context when parts get active/inactive

I am developing my own eclipse editor and need to switch between different contexts for key binding. Currently I am doing the context activation/deactivation manually upon part activation.
This page
https://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fworkbench_advext_contexts.htm says:
If you are activating a more specific Context within your part (either
View or Editor) you can use the part site service locator to active
your Context. The part's IContextService will take care of activating
and deactivating the Context as your part is activated or deactivated.
It will also dispose the Context when the part is disposed.
It seems like that is just what I want. But the page did not say how. Can anyone give me a hint what a 'part site service locator' mentioned in the text is and how to use it?
I would interpret the text so that you should use the service locator of the site that corresponds to your (editor) part. In the following example, part references your editor. By obtaining the context service from the part's site, you get a child context service for that particular part in wich you can activate a specialized editor context.
IContextService contextService = part.getSite().getService( IContextService.class );
contextService.activateContext( "your.editor.context.id" );
After digging through Eclipse code, here's my answer to my own question.
First thing first, it is JUST enough to invoke
IContextService contextService = part.getSite().getService( IContextService.class );
contextService.activateContext( "your.editor.context.id" );
anywhere after init(where you get PartSite), just as #Rüdiger Herrmann mentioned in his answer.
AND(here's my finding) NOTHING ELSE need to be done.
Eclipse will automatically activate/deactivate the context when part is activated /deactivated, just as described in the text I refer to. In addition, when the part site is disposed, all context will be disposed.
If you are interested in how, here's more digging.
Activate/Deactivate
When we invoke getSite().getService(IContextService.class), what we get is an instance of SlaveContextService.
When we call activateContext(String contextId) on it, our request will be automatically translate to a request with a default expression ActivePartExpression.
From it's name we can easily guess that this expression will check whether a part is active and do some changes. The changes it does can be seen at ContextService.UpdateExpression.changed. Here's the code(ContextService:124-128)
if (result != EvaluationResult.FALSE) {
runExternalCode(() -> contextService.activateContext(contextId));
} else if (cached != null) {
runExternalCode(() -> contextService.deactivateContext(contextId));
}
Whenever Eclipse context changes(activate/deactivate part will trigger context change), UpdateExpression.changed will be invoked and check whether the target part is still active, then activate/deactivate the context accordingly.
Dispose
In SlaveContextService.dispose, all context registered through it will be disposed upon the service's dispose.

How to detect private browsing in iOS 11 Mobile Safari or MacOS High Sierra Safari?

On the new iOS 11 Safari and MacOS High Sierra Safari, that trick of seeing if window.localStorage.setItem('test', 1); (see https://stackoverflow.com/a/17741714/1330341) throws an error no longer works, because it no longer throws an error, and it also properly sets the localStorage item. Has anyone figured out any other way to check for private browsing mode in the new versions of Safari?
Haven't actually tried it, but from reading Apple's document:
https://support.apple.com/kb/ph21413?locale=en_US
It lists various characteristics of private mode browsing (~snip):
When you use a Private Browsing window:
Each tab in the window is isolated from the others, so websites you
view in one tab can’t track your browsing in other tabs.
Safari doesn’t remember the webpages you visit or your AutoFill
information.
Safari doesn’t store your open webpages in iCloud, so they aren’t
shown when you view all your open tabs from other devices.
Your recent searches aren’t included in the results list when you use
the Smart Search field.
Items you download aren’t included in the downloads list. (The items
do remain on your computer.)
If you use Handoff, Private Browsing windows are not passed to your
iOS devices or other Mac computers.
Safari doesn’t remember changes to your cookies or other website
data. Safari also asks websites and others who provide those sites
with content (including advertisers) not to keep track of your
browsing, although it is up to the websites to honor this request.
Plug-ins that support Private Browsing stop storing cookies and other
tracking information.
From the above, in particular I found interesting that Safari specifically asks websites to "not track" the browsing. This could potentially be a mechanism to look for, to determine if using private browsing.
See this answer for an example:
Implementing Do not track in asp.net mvc
Again, haven't tested and unsure if it will work, but if not the list provides other potential options. HTH.
I find a solution here:
https://gist.github.com/cou929/7973956#gistcomment-2272103
var isPrivate = false;
try {
window.openDatabase(null, null, null, null);
} catch (_) {
isPrivate = true;
}
alert((isPrivate ? 'You\'re' : 'You aren\'t') + ' in private browsing mode');
Hope it helps :)
Quote from apple's website. https://support.apple.com/kb/ph21413?locale=en_US
Websites can’t modify information stored on your device, so services
normally available at such sites may work differently until you turn
off Private Browsing
So, store a test variable, change its value, then read the test variable.
If you get an exception, are unable to find the variable, the value didn't change or you get a null/undefined value back, they are most likely in private mode.
Alternatively, in private browsing, you have no stored search history accessible. So, redirect to a new page in your site on startup and then test if you have any previous history. If not and the fact that you are getting a Do Not Track most likely means your in private mode on safari.
Please note that I have not tested this. This is based off the information provided by Apple in the above link.
Thing that I realized is Safari throws a "Quota Exceeded" error in the Private mode. So here is what I did!
isPrivateMode: function () {
if (localStorage.length === 0) {
try {
localStorage.setItem('isLocalStorageAvaialble', 'That is being tested!');
localStorage.removeItem('isLocalStorageAvaialble');
return false;
} catch (e) {
return true;
}
}
}
Checking the length of localStorage is important for the fact that, if you are trying this method on a browser that supports localStorage, but is full, you still will get the "Quota Exceeded" error.
In private mode, the length of localStorage is always 0.
Hope this helps!

Controlling level and focus of windows other apps with CGPrivate functions

Question
How to use these private functions on other windows? It would be nice to have this knowledge back in the wild. I am specifically trying to get CGSOrderWindow and CGSSetWindowLevel to work.
I was trying in the direction of:
temporarily register as the dock and then register the dock as the dock again immediately afterwards
or
code injection into the Dock process per this comment:
Also, the author of the above project seems determined to make all core functionality available as a framework. It seems to be implemented as code injection into the Dock process.
Reason I know this is possible
I have been doing work on trying to setLevel on window of another app, and focus window of another app if focused. I am posting this again with the info I learned because from my searching online, I know this was done in the past, its just the knowledge is not publicly out there anymore. The sourceforge pages are no longer there. So I was wondering if you could help me make this information public again.
This is the topic I read that gave me this information - http://cocoadev.com/HowtoControlOtherAppsWindows
Here you see comments like:
You cannot control an another app's windows from a user-level process, unfortunately.
SlavaKarpenko
You can, Slava, you just need to register as the Dock. It might be possible to temporarily register as the dock and then register the dock as the dock again immediately afterwards, not sure. I think the call you'd be wanting to investigate as CoreDockRegisterDockOwner in HIServices.framework.
FinlayDobbie
You could also use APE or similar to do control the windows, or (as mentioned above) register as the Dock (look for the private APIs with Universal Connection in their name). Has anyone found a polite way of getting the Dock to give up its universal connection? The only way I can find is to force quit the Dock and grab the universal connection when it's not looking (which prevents the dock reloading).
SamTaylor
There's an open source project up on sourceforge.net that looks much more like the window managers I've used on Unix boxes than Space.app (or Space.dock): http://wsmanager.sourceforge.net/
SteveCook
Verifying things work
This is what I learned, from the sources at bottom of this post, we see all these functions work with CGWindowIds, so how do I get that, this is how:
Get all windows with CGWindowListCopyWindowInfo. Then access each element from that array with CFArrayGetValueAtIndex and then get the CGWindowId with objectForKey:, kCGWindowNumber, and then integerValue.
Now if I try to focus or set level of a window that is OWNED by the app running the code, it works fantastic. For instance:
MY_TARGET_CGWINDOW_ID = 179;
rez_CGError = CGSOrderWindow(_CGSDefaultConnection, MY_TARGET_CGWINDOW_ID, kCGSOrderAbove, 0);
Will focus it, rez_CGError is 0. Even if the window is minimized, it is unminimized, without animation, and shown.
Now however, if I try this on a window of a different app we get some errors:
MY_TARGET_CGWINDOW_ID_of_other_app = 40;
rez_CGError = CGSOrderWindow(_CGSDefaultConnection, MY_TARGET_CGWINDOW_ID_of_other_app, kCGSOrderAbove, 0);
This fails and rez_CGError is 1000, which I suspect means "cid (CGSConnection) used does not have permission to modify target window". The same happens if I first do [app activateWithOptions: (NSApplicationActivateIgnoringOtherApps | NSApplicationActivateAllWindows)] before making the call above.
So I first get the cid of that owning window like this:
var rez_CGError = CGSGetWindowOwner(_CGSDefaultConnection, MY_TARGET_CGWINDOW_ID_of_other_app, &ownerCid);
This works good and I get ownerCid is set to a value. Then I do the focus command with this new connection:
rez_CGError = CGSOrderWindow(ownerCid, MY_TARGET_CGWINDOW_ID_of_other_app, kCGSOrderAbove, 0);
However this gives rez_CGError of 268435459, which I suspect means "current app does not have permission to use this ConnectionId (cid)". (Same happens if I call activateWithOptions first.
My Sources for the Private Functions
Here is the sources for some private functions I found - https://code.google.com/p/undocumented-goodness/source/browse/trunk/CoreGraphics/CGSPrivate.h
This one source here contains a function that is not in the above link - CGSGetConnectionIDForPSN - i test it and it exists - from - https://github.com/mnutt/libqxt/blob/767498816dfa1742a6f3aee787281745afec11b8/src/gui/qxtwindowsystem_mac.h#L80

How to change Textmate's context menu key binding?

In Textmate there is a great shortcut to get to the context menu without using the mouse (I wish it worked systemwide!!!). It is Opt+F2.
When working on my Macbook, however, F2 is mapped to screen brightness, so I have to press fn+opt+F2, for which I have to use both hands - and that's quite uncomfortable.
Is the a way how I could map it to the right opt key, for example?
For TextMate 2 you can create ~/Library/Application Support/TextMate/KeyBindings.dict and let it contain something like:
{ "#d" = "showContextMenu:"; }
Here #d corresponds to ⌘D. See this blog post on how to construct the key equivalent strings.
Source: TextMate mailing list
Key binding files are read in the following order. A new binding for a bound key overrides the previous one:
/System/Library/Frameworks/AppKit.framework/Resources/StandardKeyBinding.dict
/Library/KeyBindings/DefaultKeyBinding.dict
~/Library/KeyBindings/DefaultKeyBinding.dict
/path/to/TextMate.app/Contents/Resources/KeyBindings.dict
~/Library/Application Support/TextMate/KeyBindings.dict
A relaunch of TextMate (⌃⌘Q) is required before changes take effect.

Kaltura - Force player to stop with API only?

Is there any way to force a Kaltura videoplayer to stop ONLY using code and the Kaltura API?
Currently I have solved it by adding a Access Control Profile named "Free preview" under Settings > Access Control in KMC and then added this profile to the Entries I've choosen.
I then add the session to the players flashvars to restrict non-members to only watch the preview, not the whole clip.
But I would like to restrict ALL, or even better selected Categories of clips by using only code, so I don't need to involve KMC.
Is that possible?
Alt) Can you create a new player in KMC and restrict it to viewing only X seconds, no matter what length of Entry? Then I can do the check if user is valid or not and get the category via API and show it in the "preview-player" och the "default player".
If I use the mediaProxy.mediaPlayTo attribute the clip stops, but is easily started again by presing play.
Would greatly appreciate an answer
I got this answer from a guy named oferc in a different forum:
You can listen to the head move event and pause the clip it goes beyond a certain time (then if someone pressed play, you can stop it again)
function jsCallbackReady(player_id) {
my_kdp = $("#"+player_id).get(0); // document.getElementById(player_id) if you do not use jquery/ prefer pure js
my_kdp.addJsListener("kdpReady", "kdpReady"); // when you load the player with an entry (and the player is ready to begin playing it using doPlay for instance)
}
function kdpReady() {
my_kdp.addJsListener("playerUpdatePlayhead","headMove");
}
function headMove(position) {
if (position > "30") { // Your Time, example 30 seconds
my_kdp.sendNotification('doStop')
}
}
Works like a charm!
fredrik_w - neither of the ways you chosen here are a good option to restrict access.
in both cases, your videos are made public, and can be easily accessible by anyone.
The best way to limit access to a video is by defining an Access Control, and like everything in Kaltura, you can define an ACL using API as well.
Check this out as a reference sample-
http://blog.kaltura.org/turning-profit-online-video-made-easy-using-paypal-html5-digital-goods