mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Add a class to find Squirrel-aware PE images
This commit is contained in:
27
src/Squirrel/NativeMethods.cs
Normal file
27
src/Squirrel/NativeMethods.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Squirrel
|
||||
{
|
||||
static class NativeMethods
|
||||
{
|
||||
[DllImport("version.dll", SetLastError = true)]
|
||||
public static extern bool GetFileVersionInfo(
|
||||
string lpszFileName,
|
||||
IntPtr dwHandleIgnored,
|
||||
int dwLen,
|
||||
[MarshalAs(UnmanagedType.LPArray)] byte[] lpData);
|
||||
|
||||
[DllImport("version.dll", SetLastError = true)]
|
||||
public static extern int GetFileVersionInfoSize(
|
||||
string lpszFileName,
|
||||
IntPtr dwHandleIgnored);
|
||||
|
||||
[DllImport("version.dll")]
|
||||
public static extern bool VerQueryValue(byte[] pBlock, string pSubBlock, out IntPtr pValue, out int len);
|
||||
}
|
||||
}
|
||||
@@ -71,12 +71,14 @@
|
||||
<Compile Include="FileDownloader.cs" />
|
||||
<Compile Include="IUpdateManager.cs" />
|
||||
<Compile Include="MarkdownSharp.cs" />
|
||||
<Compile Include="NativeMethods.cs" />
|
||||
<Compile Include="PackageExtensions.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ReleaseEntry.cs" />
|
||||
<Compile Include="ReleaseExtensions.cs" />
|
||||
<Compile Include="ReleasePackage.cs" />
|
||||
<Compile Include="ShellFile.cs" />
|
||||
<Compile Include="SquirrelAwareExecutableDetector.cs" />
|
||||
<Compile Include="TaskbarHelper.cs" />
|
||||
<Compile Include="UpdateInfo.cs" />
|
||||
<Compile Include="UpdateManager.cs" />
|
||||
|
||||
73
src/Squirrel/SquirrelAwareExecutableDetector.cs
Normal file
73
src/Squirrel/SquirrelAwareExecutableDetector.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Squirrel
|
||||
{
|
||||
static class SquirrelAwareExecutableDetector
|
||||
{
|
||||
public static int? GetPESquirrelAwareVersion(string executable)
|
||||
{
|
||||
if (!File.Exists(executable)) return null;
|
||||
var fullname = Path.GetFullPath(executable);
|
||||
|
||||
return GetAssemblySquirrelAwareVersion(fullname) ?? GetVersionBlockSquirrelAwareValue(fullname);
|
||||
}
|
||||
|
||||
static int? GetAssemblySquirrelAwareVersion(string executable)
|
||||
{
|
||||
try
|
||||
{
|
||||
var assembly = Assembly.ReflectionOnlyLoadFrom(executable);
|
||||
var attrs = assembly.GetCustomAttributesData();
|
||||
var attribute = attrs.FirstOrDefault(x =>
|
||||
{
|
||||
if (x.AttributeType != typeof(AssemblyMetadataAttribute)) return false;
|
||||
if (x.ConstructorArguments.Count != 2) return false;
|
||||
return x.ConstructorArguments[0].Value.ToString() == "SquirrelAwareVersion";
|
||||
});
|
||||
|
||||
if (attribute == null) return null;
|
||||
|
||||
int result;
|
||||
if (!Int32.TryParse(attribute.ConstructorArguments[1].Value.ToString(), NumberStyles.Integer, CultureInfo.CurrentCulture, out result))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (FileLoadException) { return null; }
|
||||
catch (BadImageFormatException) { return null; }
|
||||
}
|
||||
|
||||
static int? GetVersionBlockSquirrelAwareValue(string executable)
|
||||
{
|
||||
int size = NativeMethods.GetFileVersionInfoSize(executable, IntPtr.Zero);
|
||||
|
||||
// Nice try, buffer overflow
|
||||
if (size <= 0 || size > 4096) return null;
|
||||
|
||||
var buf = new byte[size];
|
||||
if (!NativeMethods.GetFileVersionInfo(executable, IntPtr.Zero, size, buf)) return null;
|
||||
|
||||
IntPtr result; int resultSize;
|
||||
if (!NativeMethods.VerQueryValue(buf, "\\StringFileInfo\\040904B0\\SquirrelAwareVersion", out result, out resultSize))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int ret;
|
||||
string resultData = Marshal.PtrToStringAnsi(result, resultSize-1 /* Subtract one for null terminator */);
|
||||
if (!Int32.TryParse(resultData, NumberStyles.Integer, CultureInfo.CurrentCulture, out ret)) return null;
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user