6

We provide Flash tutorial videos that install on the local (Windows) hard disk with our application. Our app uses ShellExecute to open the html file (in whatever browser is associated with html files) in which they are embedded.

Apparently there's a bug in Chrome's more recent Flash players that fails to play local files (but files over the web are fine.)

(Frankly, I'm astonished that this bug hasn't been fixed by Google. Seems like a big one to me... but maybe not many people play Flash from locations other than the web?)

There's a work-around on the about:plugins screen in Chrome, but we can't ask our users to do that. Here's a discussion of the work-around: http://techsmith.custhelp.com/app/answers/detail/a_id/3518

I want to provide my users with an option to open our html files IE. If Chrome is their default browser, then I'd show a checkbox that says something embarrassing like "If our tutorial videos fail to play, check this box to try them in IE."

Is this XE2 code (from two years ago on SO: link) still reasonable?

if pos('CHROME', UpperCase(GetAssociation('C:\Path\File.html')) > 0 then
  // Chrome is the default browser

function GetAssociation(const DocFileName: string): string;
var
  FileClass: string;
  Reg: TRegistry;
begin
  Result := '';
  Reg := TRegistry.Create(KEY_EXECUTE);
  Reg.RootKey := HKEY_CLASSES_ROOT;
  FileClass := '';
  if Reg.OpenKeyReadOnly(ExtractFileExt(DocFileName)) then
  begin
    FileClass := Reg.ReadString('');
    Reg.CloseKey;
  end;
  if FileClass <> '' then begin
    if Reg.OpenKeyReadOnly(FileClass + '\Shell\Open\Command') then
    begin
      Result := Reg.ReadString('');
      Reg.CloseKey;
    end;
  end;
  Reg.Free;
end;
Community
  • 1
  • 1
RobertFrank
  • 7,332
  • 11
  • 53
  • 99
  • HKEY_CLASSES_ROOT\Shell\Open\Command tells the Windows shell what program to use to open HTML files. To see what the user uses to browse the Internet, check HKEY_CLASSES_ROOT\.html . – cleong Aug 15 '12 at 10:11
  • Opening local HTML files containing Flash is troublesome in all three major browsers. IE throws up an ugly warning message. Firefox could crash if the SWF does something that triggers Flash's security warning window in the wrong moment. Stuff of nightmare. – cleong Aug 15 '12 at 10:52
  • It's not a bug, it's a security hole, and they closed it. – Warren P Aug 15 '12 at 19:15
  • @WarrenP: what does your "It's not a bug..." refer to? The refusal of Chrome Flash to play local files? Not to start a discussion (because I'm a novice in this), but do you think this behavior is deliberate and I should never expect Flash (in Chrome) to play files off a local drive again? I reported this issue yesterday (http://code.google.com/p/chromium/issues/detail?id=142683) and it's been assigned a priority, but of course that doesn't necessarily mean it's validated as a bug rather than closed security hole... – RobertFrank Aug 15 '12 at 23:08
  • 1
    I read the Google chrome groups and when they changed this, it was intentional. After your issue is validated, I expect you will get back a comment to that effect from someone on the team. The workaround is to turn on some property in the chrome configuration options. I believe they block not only local swf files, but all local FILE:// urls. – Warren P Aug 16 '12 at 00:13
  • If you are in fact using Google chrome, and FindExecutable returns Chrome.exe, then append `--allow-file-access-from-files` when you launch chrome, and perhaps the Flash files will play. Hope that helps! – Warren P Aug 16 '12 at 02:58
  • Google has a long standing policy to dis-allow Google Chrome from executing XSLT on local files. It is claimed to be for security reasons, but I expect there are commercial drivers. Given this, it should be completely unsurprising that Google would apply the same attitude to local SWF. – Sean B. Durkin Aug 16 '12 at 08:36

1 Answers1

4

If you have an actual full path to an existing file on disk, you can use FindExecutable instead. It's easier, and doesn't require access to the registry, but it does require that an actual file exists.

Here's a console app for XE2 that demonstrates use:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils, ShellAPI, Windows;

var
  Buffer: array[0..MAX_PATH] of Char;
  Res: Integer;

begin
  FillChar(Buffer, SizeOf(Buffer), #0);
  Res := FindExecutable(PChar('C:\Path\File.html'), nil, Buffer);
  if Res > 32 then
    Writeln('Executable is ' + Buffer)
  else
    WriteLn(SysErrorMessage(Res));
  Readln;
end.

The method you show will work, but FindExecutable is easier (less code) and works on XP and above.

Ken White
  • 123,280
  • 14
  • 225
  • 444
  • Thanks, Ken! I was initially worried about registry access, but thought that opening the keys as ReadOnly would be possible for a non-admin users. I like your solution better. Less code; less dependence on Windows internal implementation of file associations. – RobertFrank Aug 15 '12 at 01:38
  • @Robert: I misspoke about the registry issues. Your code would work fine, but is a little more complicated than `FindExecutable`. (I checked my memory, and was mistaken about exactly what `KEY_EXECUTE` meant for rights.) I edited to remove that paragraph. – Ken White Aug 15 '12 at 01:48