Get Windows to treat files with the same extension differently

10

1

Multiple programs use the same file extension, but the formats are totally different and incompatible. For instance, I have .sch files on my computer that are in at least 5 different formats (TINA, PSpice, PADS, Protel, and Eagle). Is there a way to get Windows to treat them differently, so that double-clicking on such a file opens it in the program it's meant to be opened in?

Linux uses magic numbers in the files themselves to differentiate, and only uses file extensions as a fallback plan. (All PNG files start with the bytes 89 50 4E 47 0D 0A 1A 0A, for instance, regardless of what you name them.) It would be nice if Windows could support this, but probably very difficult to implement. Maybe something simpler like a second-level extension, like filename.program1.sch and filename.program2.sch? Maybe some kind of filter that renames files on the fly?

Better idea: Associating the ambiguous extension with a pre-processor (.bat file or dedicated app) that checks for a second-level extension or goes into the file itself and scans for the magic number and then launches the appropriate program?

endolith

Posted 2011-08-02T01:17:53.577

Reputation: 6 626

1TrID may be of interest to you -- it has a database of 4400 binary signatures. – josh3736 – 2011-08-02T14:28:41.490

I remember this used to happen on the RISC OS but sometimes used to cause frustration when you had multiple apps that could process the same file type and it would open the program with the wrong program!

– Matt Wilko – 2011-08-02T14:58:53.583

@Matt: Great, thanks! http://file-extension.net/seeker/file_extension_sch

– endolith – 2011-08-03T04:03:13.437

Answers

8

I solved it myself:

I made a Python script that reads the first few bytes of a file and compares them to a dictionary, then launches the appropriate program based on the magic numbers.

import sys
import subprocess

magic_numbers = {
'OB': r'C:\Program Files (x86)\DesignSoft\Tina 9 - TI\TINA.EXE', # TINA
'*v': r'C:\Program Files (x86)\Orcad\Capture\Capture.exe', #PSpice
'DP': r'C:\Program Files (x86)\Design Explorer 99 SE\Client99SE.exe', #Protel
'\x00\xFE': r'C:\MentorGraphics\9.0PADS\SDD_HOME\Programs\powerlogic.exe', #PADS Logic
'\x10\x80': r'C:\Program Files (x86)\EAGLE-5.11.0\bin\eagle.exe', # Eagle
}

filename = sys.argv[1]
f = open(filename, 'rb')
# Read just enough bytes to match the keys
magic_n = f.read(max(map(len, magic_numbers)))

subprocess.call([magic_numbers[magic_n], filename])

Latest version will be here: Launch ambiguous files in the appropriate program

I tried to associate the file extension with this script, but Windows 7 didn't let me. It just associated it with Python instead, so I went into the registry and added the script name manually.

How to associate a file extension with a Python script

Room for improvement, but it works. I can double-click on different files with the same .sch extension and they open in different apps.

Update: I've converted it to an .exe using cx_freeze, with an external YAML config file, and it's easy to associate. See also this libmagic proposal. Not sure if I should make this into a full-fledged "libmagic launcher for Windows" or if it's better to handle only one file extension with one .exe and a simple YAML file.

endolith

Posted 2011-08-02T01:17:53.577

Reputation: 6 626

I don't grasp len(max(magic_numbers.keys())) IMHO it doesn't get the longest key – Massimo – 2020-01-13T20:10:35.857

@Massimo Hmm, yeah that's a bad idea https://stackoverflow.com/a/20463240/125507

– endolith – 2020-01-13T22:21:25.247

2This would actually be trivial to write as an exe. . . – surfasb – 2011-08-02T05:31:19.103

Not if you don't know how to write exes :) – endolith – 2011-08-02T14:26:11.537

1It wasn't a knock on ya. It was something for myself :) – surfasb – 2011-08-02T16:22:32.063

@surasb: So have you written me an .exe yet? It's trivial, right? :) – endolith – 2011-08-17T14:21:57.393

I totally forgot! I've been messing with 3D meshes on Silverlight for the past week. Later tonight, after I babysit this RAID array. . . – surfasb – 2011-08-17T16:28:59.463

@surasb: Really? My latest Python code is here. Now I'm thinking it would be best if the file type definitions were in a separate file, if any ambiguous file extension could be associated with it, and if it could differentiate by both extension and file type. .dsn OrCad schematic files have the same magic word as .doc files, for instance. disambiguator.exe

– endolith – 2011-08-17T17:29:45.857

The lazy way is to just convert the script straight to an exe. At first I was going to try to find all the registered programs in the system and make it easier to associate programs with magic numbers/file associations. But it will be faster if we just load settings through a text file. Seems easiest. – surfasb – 2011-08-17T19:24:55.463

@surasb: Did you ever do any work on this? It's about time I learned py2exe or cx_Freeze... – endolith – 2012-03-10T16:29:01.003

9

Windows does not launch files based on any information in the file - building a database for that would take an incredible amount of work and programming. The only true way to identify a file is by the binary signatures in the file, if the file even has it, and this is up to the software author to implement.

In Windows, files are passed to the program you specify for a particular file extension. Windows determines a file's extension as the substring which follows the last occurrence of a period, so it's not possible with the file names you posted.

You have to either re-name the files (and give them unique file extensions), or write a batch file to launch the appropriate application for you. For more details, see this Technet article.

Breakthrough

Posted 2011-08-02T01:17:53.577

Reputation: 32 927

1I was trying to make this work by creating a unique file extension, but even if he did, the real problem is that most programs will only recognize their own extensions despite content, and would not open them anyway. – KCotreau – 2011-08-02T01:33:08.633

2I would love to see someone do this, though. I think the way you would get around it is to have a single program open files of all extensions, and have that program keep its own database (using NTFS's alternate streams to keep track of files) and launch each respective program that the user defines for each file. It wouldn't be that much work, but I can see a lot of problems with this approach, so that's probably why no one has done it. – Sasha Chedygov – 2011-08-02T01:35:49.190

Pre-processing with a batch file is an excellent idea, though I doubt you're thinking of the same thing I'm thinking. Otherwise this answer doesn't really address the question. I already know how the normal Windows associations work. (And the database for recognizing file types already exists, so creating it wouldn't be any work, just implementing support for it in Windows.) – endolith – 2011-08-02T01:51:14.403

2it wouldn't be TOO hard - there's tools that do it (trid, or file) and most posix based oses look at file headers, and not extensions. Its less a matter of design choices, than the amount of effort it would take. Naturally this would be a lot harder for a third party, but if MS felt it was needed, this might be semi-trivial – Journeyman Geek – 2011-08-02T01:57:48.000

@endolith Windows does not have any method to detect file types. It only assumes the type based on the extension. Even metadata is only parsed if it has the proper extension. – Breakthrough – 2011-08-02T02:20:12.053

@Breakthrough: :D You gave me the idea I needed to solve the problem but you don't even realize it. – endolith – 2011-08-02T03:53:50.180

3"Using NTFS's alternate streams to keep track of files." It's obvious to me why Windows doesn't implement the Linux/POSIX model. Simply that it requires a file read. If that was the case, everytime you right clicked a file, it has to fire off an expensive file read. Even worse, imagine if it was a network file and the connection had a noticable lag. People would just blame WinDoze. Raymond Chen would bash on this technique also cause it would cause a file to be recalled if it was on a tertiary storage area. – surfasb – 2011-08-02T05:30:17.577

1But Windows does allow you to break that model. . . – surfasb – 2011-08-02T05:30:48.263

1@endolith You could make an application to launch a different program based on the hex/binary signatures in those files, that would work fine. You just need to find the unique (and constant) identifier in those file types. I don't know how to do binary file I/O with batch files in Windows, but I know it's easy enough to do with C++. – Breakthrough – 2011-08-02T10:33:25.497

@Breakthrough: Yes, that's what I did last night. See my answer. – endolith – 2011-08-02T14:27:11.473

3

To start, you can rename one of the types of files to have a new extension, and use the "open with" dialogue to set a default program to open those types of files.

This doesn't deal with the renaming problem though. But you simplify things by making a specific folder where you put all of the files from one of the programs. Then you can write a script to automatically rename files in that folder to your new file extension.

You may have trouble with an "Open File" dialogue in your program, depending on how it is set up. But if you have a single folder where all of your files are you should be able to just use that.

A more complicated, but potentially better way would be to create a proxy program. Keep all file extensions, but have them be opened by the proxy program. Have your program examine the binary and choose which type of file it is and which program to start. This will require you to spend some time writing your program, which may or may not be worth it to you.

Joel

Posted 2011-08-02T01:17:53.577

Reputation: 261

Yes, but using a wholly different extension means you often can't open the files from within the programs. – endolith – 2011-08-02T02:04:29.417

yes I pointed that out. The second method I suggested won't have that problem though. – Joel – 2011-08-02T02:13:02.797

2

Microsoft Visual Studio implements your last idea. When you launch a .sln file, a small stub checks the solution version number and launches the correct version of Visual Studio (if you've got multiple versions installed).

Of course, coordination here is a bit easier since (A) the file format is designed for this and (B) they're all versions of the same software, from the same manufacturer.

MSalters

Posted 2011-08-02T01:17:53.577

Reputation: 7 587

1

A quick solution is to add additional context entries to the explorer context menu. Or to use the 'open with' context entry. The first is more comfortable as one can add call parameters and specify 'telling' names. It also allows opening a file with different versions of the same program (if installed parallel).

Of course, this aproach is not automatic. One has to know the proper application. But for file types where the database based detection would fail (e.g. text files or other files without a "magic number"), you always have the choice.

BTW: The less-known OS 'GEOS' (which was a Win3 competitor at its tiem and far ahead) had a fixed 256 bytes header for all files where the creating application, icon an copyright notices were stored (along with a free field for own notes). As this was part of the file and not the file system or an OS dictionary, it was transparent when files were moved across file systems or even to a different OS (there was an explorer extension for W95).

Peter Painter

Posted 2011-08-02T01:17:53.577

Reputation: 11