├── .gitignore
├── .npmignore
├── IconExtractor
├── IconExtractor.sln
├── IconExtractor.v11.suo
└── IconExtractor
│ ├── App.config
│ ├── IconExtractor.csproj
│ ├── IconExtractor.csproj.user
│ ├── Program.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ └── packages.config
├── README.md
├── package.json
└── win-iconExtractor.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | packages
3 | obj
4 | bin
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | IconExtractor
2 | .gitignore
3 | win-iconExtractor-test.js
4 |
--------------------------------------------------------------------------------
/IconExtractor/IconExtractor.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconExtractor", "IconExtractor\IconExtractor.csproj", "{DB565312-D79D-4AAD-AEE0-55F4AF1A9AC2}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {DB565312-D79D-4AAD-AEE0-55F4AF1A9AC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {DB565312-D79D-4AAD-AEE0-55F4AF1A9AC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {DB565312-D79D-4AAD-AEE0-55F4AF1A9AC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {DB565312-D79D-4AAD-AEE0-55F4AF1A9AC2}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/IconExtractor/IconExtractor.v11.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScienceVikings/IconExtractor/ef365696e975634edfff4995c7839f1a0b66f48c/IconExtractor/IconExtractor.v11.suo
--------------------------------------------------------------------------------
/IconExtractor/IconExtractor/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/IconExtractor/IconExtractor/IconExtractor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {DB565312-D79D-4AAD-AEE0-55F4AF1A9AC2}
8 | Exe
9 | Properties
10 | IconExtractor
11 | IconExtractor
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
37 | False
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}
59 | 1
60 | 0
61 | 0
62 | tlbimp
63 | False
64 | True
65 |
66 |
67 |
68 |
69 | copy /Y $(TargetPath) $(SolutionDir)..\bin\$(TargetFileName)
70 |
71 |
78 |
--------------------------------------------------------------------------------
/IconExtractor/IconExtractor/IconExtractor.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/IconExtractor/IconExtractor/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Threading;
7 | using System.Drawing;
8 | using System.IO;
9 | using Newtonsoft.Json;
10 | using IWshRuntimeLibrary;
11 |
12 | namespace IconExtractor {
13 |
14 | class IconRequest {
15 |
16 | public string Context { get; set; }
17 | public string Path { get; set; }
18 | public string Base64ImageData { get; set; }
19 |
20 | }
21 |
22 | class Program {
23 |
24 | private static bool useShortcutPath;
25 |
26 | static void Main(string[] args) {
27 |
28 | // https://msdn.microsoft.com/en-us/library/ms404308%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
29 |
30 | Console.InputEncoding = UTF8Encoding.UTF8;
31 | Console.OutputEncoding = UTF8Encoding.UTF8;
32 |
33 | useShortcutPath = args.Length > 0 && args[0] == "-x";
34 |
35 | while (true) {
36 |
37 | string input = Console.In.ReadLine().Trim();
38 | IconRequest data = JsonConvert.DeserializeObject(input);
39 |
40 | try {
41 |
42 | data.Base64ImageData = getIconAsBase64(data.Path);
43 | Console.WriteLine(JsonConvert.SerializeObject(data));
44 |
45 | } catch (Exception ex) {
46 | Console.Error.WriteLine(ex);
47 | Console.Error.WriteLine(input);
48 | }
49 |
50 | }
51 |
52 | }
53 |
54 | static string getIconAsBase64(string path) {
55 |
56 | if (useShortcutPath && path.EndsWith(".lnk")) {
57 | path = getShortcutTarget(path);
58 | }
59 |
60 | Icon iconForPath = SystemIcons.Application;
61 |
62 | if (System.IO.File.Exists(path)) {
63 | iconForPath = Icon.ExtractAssociatedIcon(path);
64 | }
65 |
66 | ImageConverter vert = new ImageConverter();
67 | byte[] data = (byte[])vert.ConvertTo(iconForPath.ToBitmap(), typeof(byte[]));
68 |
69 | return Convert.ToBase64String(data);
70 |
71 | }
72 |
73 | static string getShortcutTarget(string path) {
74 |
75 | if (!System.IO.File.Exists(path)) {
76 | return "";
77 | }
78 |
79 | WshShell shell = new WshShell();
80 | IWshShortcut lnk = (IWshShortcut)shell.CreateShortcut(path);
81 | return lnk.TargetPath;
82 |
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/IconExtractor/IconExtractor/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("IconExtractor")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Hewlett-Packard")]
12 | [assembly: AssemblyProduct("IconExtractor")]
13 | [assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("77c0815d-998c-4fef-8c27-f7ef7f49740d")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/IconExtractor/IconExtractor/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IconExtractor
2 |
3 | A nodejs package that returns base64 image data for a path's icon.
4 |
5 | This is a simple nodejs wrapper around a .net executable that will extract icon image data from a given path and return it.
6 |
7 | Get an instance of the icon extractor with
8 |
9 | `var iconExtractor = require('icon-extractor');`
10 |
11 | This object contains an event emitter with two events, `icon` and `error`
12 |
13 | To get an icon's data you need to call the `getIcon` function which takes two parameters.
14 | The first is a context parameter. This will return with the icon data so you can have some information about what the return
15 | data is for. The second parameter is the path of the file you want the icon for.
16 |
17 | Then, you need to listen on the emitter for the icon data like this
18 |
19 | `iconExtractor.emitter.on('icon', function(iconData){ /*do stuff here*/ });`
20 |
21 | This data comes back as a json object containing three fields, `Context`, `Path` and `Base64ImageData`
22 |
23 | Here is an example of it all put together
24 |
25 | ```
26 | var iconExtractor = require('icon-extractor');
27 |
28 | iconExtractor.emitter.on('icon', function(data){
29 | console.log('Here is my context: ' + data.Context);
30 | console.log('Here is the path it was for: ' + data.Path);
31 | console.log('Here is the base64 image: ' + data.Base64ImageData);
32 | });
33 |
34 | iconExtractor.getIcon('SomeContextLikeAName','c:\myexecutable.exe');
35 | ```
36 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "icon-extractor",
3 | "version": "1.0.3",
4 | "description": "Given a path, return base64 data of the icon used for that file",
5 | "main": "win-iconExtractor.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/ScienceVikings/IconExtractor.git"
12 | },
13 | "keywords": [
14 | "icon",
15 | "extractor",
16 | "windows"
17 | ],
18 | "author": "Justin Basinger",
19 | "license": "MIT",
20 | "bugs": {
21 | "url": "https://github.com/ScienceVikings/IconExtractor/issues"
22 | },
23 | "homepage": "https://github.com/ScienceVikings/IconExtractor#readme",
24 | "dependencies": {
25 | "lodash": "^3.10.1"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/win-iconExtractor.js:
--------------------------------------------------------------------------------
1 | var EventEmitter = require('events');
2 | var fs = require('fs');
3 | var child_process = require('child_process');
4 | var _ = require('lodash');
5 | var os = require('os');
6 | var path = require('path');
7 |
8 | var emitter = new EventEmitter();
9 |
10 | function IconExtractor(){
11 |
12 | var self = this;
13 | var iconDataBuffer = "";
14 |
15 | this.emitter = new EventEmitter();
16 | this.iconProcess = child_process.spawn(getPlatformIconProcess(),['-x']);
17 |
18 | this.getIcon = function(context, path){
19 | var json = JSON.stringify({context: context, path: path}) + "\n";
20 | self.iconProcess.stdin.write(json);
21 | }
22 |
23 | this.iconProcess.stdout.on('data', function(data){
24 |
25 | var str = (new Buffer(data, 'utf8')).toString('utf8');
26 |
27 | iconDataBuffer += str;
28 |
29 | //Bail if we don't have a complete string to parse yet.
30 | if (!_.endsWith(str, '\n')){
31 | return;
32 | }
33 |
34 | //We might get more than one in the return, so we need to split that too.
35 | _.each(iconDataBuffer.split('\n'), function(buf){
36 |
37 | if(!buf || buf.length == 0){
38 | return;
39 | }
40 |
41 | try{
42 | self.emitter.emit('icon', JSON.parse(buf));
43 | } catch(ex){
44 | self.emitter.emit('error', ex);
45 | }
46 |
47 | });
48 | });
49 |
50 | this.iconProcess.on('error', function(err){
51 | self.emitter.emit('error', err.toString());
52 | });
53 |
54 | this.iconProcess.stderr.on('data', function(err){
55 | self.emitter.emit('error', err.toString());
56 | });
57 |
58 | function getPlatformIconProcess(){
59 | if(os.type() == 'Windows_NT'){
60 | return path.join(__dirname,'/bin/IconExtractor.exe');
61 | //Do stuff here to get the icon that doesn't have the shortcut thing on it
62 | } else {
63 | throw('This platform (' + os.type() + ') is unsupported =(');
64 | }
65 | }
66 |
67 | }
68 |
69 | module.exports = new IconExtractor();
70 |
--------------------------------------------------------------------------------