├── .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 | --------------------------------------------------------------------------------