├── .gitignore ├── LICENSE ├── README.md ├── dll2lib.sln └── dll2lib ├── App.config ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── bin └── Release │ └── dll2lib.exe └── dll2lib.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Oo]bj/ 3 | 4 | # mstest test results 5 | TestResults 6 | 7 | ## Ignore Visual Studio temporary files, build results, and 8 | ## files generated by popular Visual Studio add-ons. 9 | 10 | # User-specific files 11 | *.suo 12 | *.user 13 | *.sln.docstates 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | dll2lib/bin/[Rr]elease/*.vshost.exe 18 | dll2lib/bin/[Rr]elease/*.manifest 19 | dll2lib/bin/[Rr]elease/*.config 20 | x64/ 21 | *_i.c 22 | *_p.c 23 | *.ilk 24 | *.meta 25 | *.obj 26 | *.pch 27 | *.pdb 28 | *.pgc 29 | *.pgd 30 | *.rsp 31 | *.sbr 32 | *.tlb 33 | *.tli 34 | *.tlh 35 | *.tmp 36 | *.log 37 | *.vspscc 38 | *.vssscc 39 | .builds 40 | 41 | # Visual C++ cache files 42 | ipch/ 43 | *.aps 44 | *.ncb 45 | *.opensdf 46 | *.sdf 47 | 48 | # Visual Studio profiler 49 | *.psess 50 | *.vsp 51 | *.vspx 52 | 53 | # Guidance Automation Toolkit 54 | *.gpState 55 | 56 | # ReSharper is a .NET coding add-in 57 | _ReSharper* 58 | 59 | # NCrunch 60 | *.ncrunch* 61 | .*crunch*.local.xml 62 | 63 | # Installshield output folder 64 | [Ee]xpress 65 | 66 | # DocProject is a documentation generator add-in 67 | DocProject/buildhelp/ 68 | DocProject/Help/*.HxT 69 | DocProject/Help/*.HxC 70 | DocProject/Help/*.hhc 71 | DocProject/Help/*.hhk 72 | DocProject/Help/*.hhp 73 | DocProject/Help/Html2 74 | DocProject/Help/html 75 | 76 | # Click-Once directory 77 | publish 78 | 79 | # Publish Web Output 80 | *.Publish.xml 81 | 82 | # NuGet Packages Directory 83 | packages 84 | 85 | # Windows Azure Build Output 86 | csx 87 | *.build.csdef 88 | 89 | # Windows Store app package directory 90 | AppPackages/ 91 | 92 | # Others 93 | [Oo]bj 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | 104 | # Backup & report files from converting an old project file to a newer 105 | # Visual Studio version. Backup files are not needed, because we have git ;-) 106 | _UpgradeReport_Files/ 107 | Backup*/ 108 | UpgradeLog*.XML 109 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Peter Nelson (peter@peterdn.com) 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | dll2lib 2 | ======= 3 | 4 | ## Summary 5 | 6 | Produces an import library (.lib) from a target dynamic link library (.dll). 7 | 8 | Requires `dumpbin.exe` and `lib.exe` in `%PATH%`. Easiest to run from the Visual Studio tools command prompt. 9 | 10 | ### Usage 11 | 12 | For ease of use, a pre-built binary is provided in `dll2lib\bin\Release`, however feel free to build your own. 13 | 14 | dll2lib.exe 15 | 16 | Options: 17 | 18 | /NOCLEAN don't delete intermediate files 19 | 20 | The import library file is output to the same directory as the target dll. 21 | 22 | ## Building 23 | 24 | Open in Visual Studio 2012+ and hit build, or build from Visual Studio tools command prompt: 25 | 26 | msbuild /p:Configuration=Release 27 | -------------------------------------------------------------------------------- /dll2lib.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dll2lib", "dll2lib\dll2lib.csproj", "{7D25AD5A-0739-4CA8-BD79-FF6D51B175DE}" 5 | EndProject 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DE9D8BD7-8F23-4D27-AD3A-029A961BADDD}" 7 | ProjectSection(SolutionItems) = preProject 8 | LICENSE = LICENSE 9 | README.md = README.md 10 | EndProjectSection 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {7D25AD5A-0739-4CA8-BD79-FF6D51B175DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {7D25AD5A-0739-4CA8-BD79-FF6D51B175DE}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {7D25AD5A-0739-4CA8-BD79-FF6D51B175DE}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {7D25AD5A-0739-4CA8-BD79-FF6D51B175DE}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /dll2lib/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /dll2lib/Program.cs: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015, Peter Nelson (peter@peterdn.com) 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | using System; 28 | using System.Diagnostics; 29 | using System.IO; 30 | using System.Linq; 31 | 32 | namespace dll2lib 33 | { 34 | static class ExtensionMethods 35 | { 36 | public static string ReadRequiredLine(this StreamReader reader) 37 | { 38 | var line = reader.ReadLine(); 39 | if (line == null) 40 | throw new InvalidDataException("Unexpected end of file"); 41 | return line; 42 | } 43 | } 44 | 45 | class Program 46 | { 47 | private static readonly string[] PRIVATES = 48 | { 49 | "DllCanUnloadNow", 50 | "DllGetClassObject", 51 | "DllGetClassFactoryFromClassString", 52 | "DllGetDocumentation", 53 | "DllInitialize", 54 | "DllInstall", 55 | "DllRegisterServer", 56 | "DllRegisterServerEx", 57 | "DllRegisterServerExW", 58 | "DllUnload", 59 | "DllUnregisterServer", 60 | "RasCustomDeleteEntryNotify", 61 | "RasCustomDial", 62 | "RasCustomDialDlg", 63 | "RasCustomEntryDlg" 64 | }; 65 | 66 | static int Main(string[] args) 67 | { 68 | if (args.Length < 1) 69 | return Usage(); 70 | 71 | var dllpath = ""; 72 | var cleanfiles = true; 73 | foreach (var arg in args) 74 | { 75 | if (arg.ToLower() == "/noclean") 76 | cleanfiles = false; 77 | else if (dllpath.Length == 0) 78 | dllpath = arg; 79 | else 80 | return Usage(); 81 | } 82 | 83 | if (!File.Exists(dllpath)) 84 | return Usage(string.Format("Could not find input file {0}", dllpath)); 85 | 86 | var index = dllpath.LastIndexOf('.'); 87 | var dllname = index >= 0 ? dllpath.Substring(0, index) : dllpath; 88 | 89 | var dmppath = dllname + ".dmp"; 90 | var defpath = dllname + ".def"; 91 | var libpath = dllname + ".lib"; 92 | 93 | try 94 | { 95 | RunDumpbin(dllpath, dmppath); 96 | } 97 | catch (Exception ex) 98 | { 99 | Console.WriteLine("RunDumpbin: " + ex.Message); 100 | return -1; 101 | } 102 | 103 | try 104 | { 105 | Dump2Def(dmppath, defpath); 106 | } 107 | catch (Exception ex) 108 | { 109 | Console.WriteLine("Dump2Def: " + ex.Message); 110 | return -1; 111 | } 112 | finally 113 | { 114 | if (cleanfiles && File.Exists(dmppath)) 115 | File.Delete(dmppath); 116 | } 117 | 118 | try 119 | { 120 | 121 | RunLib(defpath, libpath); 122 | } 123 | catch (Exception ex) 124 | { 125 | Console.WriteLine("RunLib: " + ex.Message); 126 | return -1; 127 | } 128 | finally 129 | { 130 | if (cleanfiles && File.Exists(defpath)) 131 | File.Delete(defpath); 132 | } 133 | 134 | return 0; 135 | } 136 | 137 | private static void RunDumpbin(string dllpath, string dmppath) 138 | { 139 | var procinfo = new ProcessStartInfo("dumpbin", string.Format("/out:{0} /exports {1}", dmppath, dllpath)); 140 | procinfo.UseShellExecute = false; 141 | var dumpbin = Process.Start(procinfo); 142 | dumpbin.WaitForExit(); 143 | if (dumpbin.ExitCode != 0) 144 | throw new ApplicationException(string.Format("dumpbin failed with exit code {0}", dumpbin.ExitCode)); 145 | } 146 | 147 | private static void RunLib(string defpath, string libpath) 148 | { 149 | var procinfo = new ProcessStartInfo("lib", string.Format("/machine:arm /def:{0} /out:{1}", defpath, libpath)); 150 | procinfo.UseShellExecute = false; 151 | var lib = Process.Start(procinfo); 152 | lib.WaitForExit(); 153 | if (lib.ExitCode != 0) 154 | throw new ApplicationException(string.Format("lib failed with exit code {0}", lib.ExitCode)); 155 | } 156 | 157 | private static void Dump2Def(string dmppath, string defpath) 158 | { 159 | using (var dmpfile = new StreamReader(File.OpenRead(dmppath))) 160 | { 161 | using (var deffile = new StreamWriter(File.OpenWrite(defpath))) 162 | { 163 | // skip header 164 | for (int i = 0; i < 3; ++i) 165 | dmpfile.ReadRequiredLine(); 166 | 167 | // check input file type 168 | var next = dmpfile.ReadRequiredLine().Trim(); 169 | if (next != "File Type: DLL") 170 | { 171 | throw new InvalidDataException(String.Format("Unexpected file type: {0}", next)); 172 | } 173 | 174 | // skip info lines 175 | for (int i = 0; i < 10; ++i) 176 | dmpfile.ReadRequiredLine(); 177 | 178 | // assert next 2 lines are what we expect 179 | if (!dmpfile.ReadRequiredLine().TrimStart().StartsWith("ordinal")) 180 | throw new InvalidDataException("Unexpected input; expected 'ordinal'"); 181 | 182 | if (dmpfile.ReadRequiredLine().Trim().Length != 0) 183 | throw new InvalidDataException("Unexpected input; expected empty line"); 184 | 185 | // begin exports 186 | deffile.WriteLine("EXPORTS"); 187 | while (true) 188 | { 189 | var line = dmpfile.ReadRequiredLine(); 190 | 191 | if (line.Length == 0) 192 | break; 193 | 194 | var words = line.Split(' '); 195 | var index = words.Length - 1; 196 | var hasforward = words[index].EndsWith(")"); 197 | if (hasforward) 198 | index -= 3; 199 | 200 | var proc = words[index]; 201 | if (proc != "[NONAME]") 202 | { 203 | deffile.Write(proc); 204 | if (PRIVATES.Contains(proc)) 205 | deffile.Write(" PRIVATE"); 206 | deffile.WriteLine(); 207 | } 208 | } 209 | 210 | // assert begin of summary 211 | if (!dmpfile.ReadRequiredLine().Trim().StartsWith("Summary")) 212 | throw new InvalidDataException(); 213 | } 214 | } 215 | } 216 | 217 | private static int Usage(string message = "") 218 | { 219 | if (message.Length > 0) 220 | Console.WriteLine(message); 221 | else 222 | { 223 | Console.WriteLine("Usage: dll2lib.exe "); 224 | Console.WriteLine(); 225 | Console.WriteLine(" options:"); 226 | Console.WriteLine(); 227 | Console.WriteLine(" /NOCLEAN don't delete intermediate files"); 228 | } 229 | return -1; 230 | } 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /dll2lib/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("dll2lib")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("dll2lib")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 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("c011ba54-89f0-4873-b571-9271683b05f0")] 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 | -------------------------------------------------------------------------------- /dll2lib/bin/Release/dll2lib.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterdn/dll2lib/7e736b3ee2d674788b5431ca13f40d70ab527f6b/dll2lib/bin/Release/dll2lib.exe -------------------------------------------------------------------------------- /dll2lib/dll2lib.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {7D25AD5A-0739-4CA8-BD79-FF6D51B175DE} 8 | Exe 9 | Properties 10 | dll2lib 11 | dll2lib 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 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 58 | --------------------------------------------------------------------------------