Merge branch 'master' into net6

This commit is contained in:
2023-01-02 14:36:27 +01:00
10 changed files with 445 additions and 21 deletions

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Pilz.Cryptography
{
public interface IUniquieID
{
bool HasID { get; }
string ID { get; }
void GenerateIfNull();
void Generate();
bool Equals(object obj);
}
}

View File

@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace Pilz.Cryptography
{
public class UniquieID<TargetType>
public class UniquieID<TargetType> : IUniquieID
{
private static int currentSimpleID = 0;
@@ -72,27 +72,60 @@ namespace Pilz.Cryptography
return hash;
}
private static string Win32_PhysicalMedia_SerialNumber = null;
private static string TryGetSerialNumberOfFirstHardDrive()
{
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
var sn = string.Empty;
foreach (ManagementObject wmi_HD in searcher.Get())
if (Win32_PhysicalMedia_SerialNumber == null)
{
if (string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
sn = wmi_HD["SerialNumber"].ToString().Trim();
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
var sn = string.Empty;
foreach (ManagementObject wmi_HD in searcher.Get())
{
if (string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
sn = wmi_HD["SerialNumber"].ToString().Trim();
}
Win32_PhysicalMedia_SerialNumber = sn;
}
return sn;
return Win32_PhysicalMedia_SerialNumber;
}
public override string ToString() => ID;
public override bool Equals(object obj)
{
var res = false;
var iD = obj as UniquieID<TargetType>;
return iD != null &&
_iD == iD._iD;
if (iD is object)
{
if (ReferenceEquals(res, iD))
res = true;
else
{
var leftHasID = iD.HasID;
var rightHasID = HasID;
if (!leftHasID && iD.GenerateOnGet)
{
iD.Generate();
leftHasID = iD.HasID;
}
if (!rightHasID && GenerateOnGet)
{
Generate();
rightHasID = HasID;
}
if (leftHasID && rightHasID)
res = _iD.Equals(iD._iD);
}
}
return res;
}
public override int GetHashCode()
@@ -104,7 +137,7 @@ namespace Pilz.Cryptography
public static implicit operator UniquieID<TargetType>(string id) => new UniquieID<TargetType>() { ID = id };
public static implicit operator UniquieID<TargetType>(int id) => new UniquieID<TargetType>() { ID = Convert.ToString(id) };
public static bool operator ==(UniquieID<TargetType> left, UniquieID<TargetType> right) => left.ID == right.ID;
public static bool operator !=(UniquieID<TargetType> left, UniquieID<TargetType> right) => left.ID != right.ID;
public static bool operator ==(UniquieID<TargetType> left, UniquieID<TargetType> right) => left.ID.Equals(right.ID);
public static bool operator !=(UniquieID<TargetType> left, UniquieID<TargetType> right) => !left.ID.Equals(right.ID);
}
}

View File

@@ -1,4 +1,4 @@
Imports System.Runtime.CompilerServices
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms
Namespace Utils
@@ -6,10 +6,19 @@ Namespace Utils
Public Module DrawingControl
Private Const WM_SETREDRAW = 11
Private ReadOnly dicSuspendCount As New Dictionary(Of IntPtr, Integer)
<Extension>
Public Sub SuspendDrawing(control As Control)
SendMessage(control.Handle, WM_SETREDRAW, False, 0)
If Not dicSuspendCount.ContainsKey(control.Handle) Then
dicSuspendCount.Add(control.Handle, 1)
Else
dicSuspendCount(control.Handle) += 1
End If
If dicSuspendCount(control.Handle) = 1 Then
SendMessage(control.Handle, WM_SETREDRAW, False, 0)
End If
End Sub
<Extension>
@@ -19,8 +28,19 @@ Namespace Utils
<Extension>
Public Sub ResumeDrawing(control As Control, redraw As Boolean)
SendMessage(control.Handle, WM_SETREDRAW, True, 0)
If redraw Then control.Refresh()
Dim doRedraw As Boolean = True
If dicSuspendCount.ContainsKey(control.Handle) Then
dicSuspendCount(control.Handle) -= 1
If dicSuspendCount(control.Handle) >= 1 Then
doRedraw = False
End If
End If
If doRedraw Then
SendMessage(control.Handle, WM_SETREDRAW, True, 0)
If redraw Then control.Refresh()
End If
End Sub
End Module

View File

@@ -1,5 +1,7 @@
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports Pilz.Win32.Mapped
Imports Pilz.Win32.Native
Namespace Internals
@@ -10,10 +12,11 @@ Namespace Internals
''' Extrahiert das Icon aus einer Datei oder aus einem Ordner.
''' </summary>
''' <param name="FilePath">Hier übergeben Sie den Pfad der Datei von dem das Icon extrahiert werden soll.</param>
''' <param name="Small">Bei übergabe von true wird ein kleines und bei false ein großes Icon zurück gegeben.</param>
Public Shared Function ExtractIcon(FilePath As String, Small As Boolean) As Icon
''' <param name="size">Bei übergabe von true wird ein kleines und bei false ein großes Icon zurück gegeben.</param>
Public Shared Function ExtractIcon(FilePath As String, size As SystemIconSize) As Icon
Dim icon As Icon
Dim shinfo As New SHFILEINFO
Dim small As Boolean = size = SystemIconSize.Small
LibShell32.SHGetFileInfo(FilePath, 0, shinfo, Math.Truncate(Marshal.SizeOf(shinfo)), SHFILEINFO.SHGFI_ICON Or If(Small, SHFILEINFO.SHGFI_SMALLICON, SHFILEINFO.SHGFI_LARGEICON))

View File

@@ -0,0 +1,208 @@
Imports System
Imports System.Runtime.InteropServices
Imports Microsoft.Win32
Imports System.Reflection
Imports System.Collections.Generic
Imports System.Drawing
Imports Pilz.Win32.Native
Imports Pilz.Win32.Native.Shell32
Imports Pilz.Win32.Mapped
Namespace Internals
Public Class IconFactory
#Region "Custom exceptions class"
Public Class IconNotFoundException
Inherits Exception
Public Sub New(ByVal fileName As String, ByVal index As Integer)
MyBase.New(String.Format("Icon with Id = {0} wasn't found in file {1}", index, fileName))
End Sub
End Class
Public Class UnableToExtractIconsException
Inherits Exception
Public Sub New(ByVal fileName As String, ByVal firstIconIndex As Integer, ByVal iconCount As Integer)
MyBase.New(String.Format("Tryed to extract {2} icons starting from the one with id {1} from the ""{0}"" file but failed", fileName, firstIconIndex, iconCount))
End Sub
End Class
#End Region
''' <summary>
''' Get the number of icons in the specified file.
''' </summary>
''' <param name="fileName">Full path of the file to look for.</param>
''' <returns></returns>
Private Shared Function GetIconsCountInFile(fileName As String) As Integer
Return ExtractIconEx(fileName, -1, Nothing, Nothing, 0)
End Function
#Region "ExtractIcon-like functions"
Public Shared Sub ExtractEx(ByVal fileName As String, ByVal largeIcons As List(Of Icon), ByVal smallIcons As List(Of Icon), ByVal firstIconIndex As Integer, ByVal iconCount As Integer)
'
' Memory allocations
'
Dim smallIconsPtrs As IntPtr() = Nothing
Dim largeIconsPtrs As IntPtr() = Nothing
If smallIcons IsNot Nothing Then
smallIconsPtrs = New IntPtr(iconCount - 1) {}
End If
If largeIcons IsNot Nothing Then
largeIconsPtrs = New IntPtr(iconCount - 1) {}
End If
'
' Call to native Win32 API
'
Dim apiResult = ExtractIconEx(fileName, firstIconIndex, largeIconsPtrs, smallIconsPtrs, iconCount)
If apiResult <> iconCount Then
Throw New UnableToExtractIconsException(fileName, firstIconIndex, iconCount)
End If
'
' Fill lists
'
If smallIcons IsNot Nothing Then
smallIcons.Clear()
For Each actualIconPtr In smallIconsPtrs
smallIcons.Add(Icon.FromHandle(actualIconPtr))
Next
End If
If largeIcons IsNot Nothing Then
largeIcons.Clear()
For Each actualIconPtr In largeIconsPtrs
largeIcons.Add(Icon.FromHandle(actualIconPtr))
Next
End If
End Sub
Public Shared Function ExtractEx(ByVal fileName As String, ByVal size As SystemIconSize, ByVal firstIconIndex As Integer, ByVal iconCount As Integer) As List(Of Icon)
Dim iconList As New List(Of Icon)()
Select Case size
Case SystemIconSize.Large
ExtractEx(fileName, iconList, Nothing, firstIconIndex, iconCount)
Case SystemIconSize.Small
ExtractEx(fileName, Nothing, iconList, firstIconIndex, iconCount)
Case Else
Throw New ArgumentOutOfRangeException("size")
End Select
Return iconList
End Function
Public Shared Sub Extract(ByVal fileName As String, ByVal largeIcons As List(Of Icon), ByVal smallIcons As List(Of Icon))
Dim iconCount = GetIconsCountInFile(fileName)
ExtractEx(fileName, largeIcons, smallIcons, 0, iconCount)
End Sub
Public Shared Function Extract(ByVal fileName As String, ByVal size As SystemIconSize) As List(Of Icon)
Dim iconCount = GetIconsCountInFile(fileName)
Return ExtractEx(fileName, size, 0, iconCount)
End Function
Public Shared Function ExtractOne(ByVal fileName As String, ByVal index As Integer, ByVal size As SystemIconSize) As Icon
Try
Dim iconList = ExtractEx(fileName, size, index, 1)
Return iconList(0)
Catch __unusedUnableToExtractIconsException1__ As UnableToExtractIconsException
Throw New IconNotFoundException(fileName, index)
End Try
End Function
Public shared Sub ExtractOne(ByVal fileName As String, ByVal index As Integer, <Out> ByRef largeIcon As Icon, <Out> ByRef smallIcon As Icon)
Dim smallIconList As List(Of Icon) = New List(Of Icon)()
Dim largeIconList As List(Of Icon) = New List(Of Icon)()
Try
ExtractEx(fileName, largeIconList, smallIconList, index, 1)
largeIcon = largeIconList(0)
smallIcon = smallIconList(0)
Catch __unusedUnableToExtractIconsException1__ As UnableToExtractIconsException
Throw New IconNotFoundException(fileName, index)
End Try
End Sub
#End Region
'this will look throw the registry
'to find if the Extension have an icon.
Public Shared Function IconFromExtension(ByVal extension As String, ByVal size As SystemIconSize) As Icon
' Add the '.' to the extension if needed
If extension(0) <> "."c Then extension = "."c & extension
'opens the registry for the wanted key.
Dim Root = Registry.ClassesRoot
Dim ExtensionKey = Root.OpenSubKey(extension)
ExtensionKey.GetValueNames()
Dim ApplicationKey As RegistryKey = Root.OpenSubKey(ExtensionKey.GetValue("").ToString())
'gets the name of the file that have the icon.
Dim IconLocation As String = ApplicationKey.OpenSubKey("DefaultIcon").GetValue("").ToString()
Dim IconPath = IconLocation.Split(","c)
If Equals(IconPath(1), Nothing) Then IconPath(1) = "0"
Dim Large = New IntPtr(0) {}, Small = New IntPtr(0) {}
'extracts the icon from the file.
ExtractIconEx(IconPath(0), Convert.ToInt16(IconPath(1)), Large, Small, 1)
Return If(size = SystemIconSize.Large, Icon.FromHandle(Large(0)), Icon.FromHandle(Small(0)))
End Function
Public Shared Function IconFromExtensionShell(ByVal extension As String, ByVal size As SystemIconSize) As Icon
'add '.' if nessesry
If extension(0) <> "."c Then extension = "."c & extension
'temp struct for getting file shell info
Dim fileInfo As SHFILEINFO = New SHFILEINFO()
SHGetFileInfo(extension, 0, fileInfo, Marshal.SizeOf(fileInfo), FileInfoFlags.SHGFI_ICON Or FileInfoFlags.SHGFI_USEFILEATTRIBUTES Or CType(size, FileInfoFlags))
Return Icon.FromHandle(fileInfo.hIcon)
End Function
Public Shared Function IconFromResource(ByVal resourceName As String) As Icon
Dim assembly As Assembly = Assembly.GetCallingAssembly()
Return New Icon(assembly.GetManifestResourceStream(resourceName))
End Function
''' <summary>
''' Parse strings in registry who contains the name of the icon and
''' the index of the icon an return both parts.
''' </summary>
''' <param name="regString">The full string in the form "path,index" as found in registry.</param>
''' <param name="fileName">The "path" part of the string.</param>
''' <param name="index">The "index" part of the string.</param>
Public Shared Sub ExtractInformationsFromRegistryString(ByVal regString As String, <Out> ByRef fileName As String, <Out> ByRef index As Integer)
If Equals(regString, Nothing) Then
Throw New ArgumentNullException("regString")
End If
If regString.Length = 0 Then
Throw New ArgumentException("The string should not be empty.", "regString")
End If
index = 0
Dim strArr = regString.Replace("""", "").Split(","c)
fileName = strArr(0).Trim()
If strArr.Length > 1 Then
Call Integer.TryParse(strArr(1).Trim(), index)
End If
End Sub
Public Shared Function ExtractFromRegistryString(ByVal regString As String, ByVal size As SystemIconSize) As Icon
Dim fileName As String
Dim index As Integer
ExtractInformationsFromRegistryString(regString, fileName, index)
Return ExtractOne(fileName, index, size)
End Function
End Class
End Namespace

View File

@@ -0,0 +1,17 @@
Imports System.Drawing
Namespace Mapped
Public Module IconExtractor
Public Function ExtractIconFromFilePath(filePath As String, size As SystemIconSize) As Icon
Return Internals.IconExtractor.ExtractIcon(filePath, size)
End Function
Public Function ExtractIconFromFileExtension(fileExtension As String, size As SystemIconSize)
Return Internals.IconFactory.IconFromExtensionShell(fileExtension, size)
End Function
End Module
End Namespace

View File

@@ -0,0 +1,12 @@
Namespace Mapped
''' <summary>
''' Two constants extracted from the FileInfoFlags, the only that are
''' meaningfull for the user of this class.
''' </summary>
Public Enum SystemIconSize As Integer
Large
Small
End Enum
End Namespace

View File

@@ -0,0 +1,20 @@
Namespace Native
<Flags>
Public Enum FileInfoFlags As Integer
''' <summary>
''' Retrieve the handle to the icon that represents the file and the index
''' of the icon within the system image list. The handle is copied to the
''' hIcon member of the structure specified by psfi, and the index is copied
''' to the iIcon member.
''' </summary>
SHGFI_ICON = &H100
''' <summary>
''' Indicates that the function should not attempt to access the file
''' specified by pszPath. Rather, it should act as if the file specified by
''' pszPath exists with the file attributes passed in dwFileAttributes.
''' </summary>
SHGFI_USEFILEATTRIBUTES = &H10
End Enum
End Namespace

View File

@@ -2,18 +2,43 @@
Namespace Native
''' <summary>
''' Contains information about a file object.
''' </summary>
<StructLayout(LayoutKind.Sequential)>
Public Structure SHFILEINFO
Public Const SHGFI_ICON As UInteger = &H100
Public Const SHGFI_LARGEICON As UInteger = &H0
Public Const SHGFI_SMALLICON As UInteger = &H1
''' <summary>
''' Handle to the icon that represents the file. You are responsible for
''' destroying this handle with DestroyIcon when you no longer need it.
''' </summary>
Public hIcon As IntPtr
''' <summary>
''' Index of the icon image within the system image list.
''' </summary>
Public iIcon As IntPtr
''' <summary>
''' Array of values that indicates the attributes of the file object.
''' For information about these values, see the IShellFolder::GetAttributesOf
''' method.
''' </summary>
Public dwAttributes As UInteger
''' <summary>
''' String that contains the name of the file as it appears in the Microsoft
''' Windows Shell, or the path and file name of the file that contains the
''' icon representing the file.
''' </summary>
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)>
Public szDisplayName As String
''' <summary>
''' String that describes the type of file.
''' </summary>
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)>
Public szTypeName As String
End Structure

View File

@@ -0,0 +1,70 @@
Imports System.Runtime.InteropServices
Namespace Native
Public Class Shell32
''' <summary>
''' Creates an array of handles to large or small icons extracted from
''' the specified executable file, dynamic-link library (DLL), or icon
''' file.
''' </summary>
''' <param name="lpszFile">
''' Name of an executable file, DLL, or icon file from which icons will
''' be extracted.
''' </param>
''' <param name="nIconIndex">
''' <para>
''' Specifies the zero-based index of the first icon to extract. For
''' example, if this value is zero, the function extracts the first
''' icon in the specified file.
''' </para>
''' <para>
''' If this value is <20>1 and <paramrefname="phiconLarge"/> and
''' <paramrefname="phiconSmall"/> are both NULL, the function returns
''' the total number of icons in the specified file. If the file is an
''' executable file or DLL, the return value is the number of
''' RT_GROUP_ICON resources. If the file is an .ico file, the return
''' value is 1.
''' </para>
''' <para>
''' Windows 95/98/Me, Windows NT 4.0 and later: If this value is a
''' negative number and either <paramrefname="phiconLarge"/> or
''' <paramrefname="phiconSmall"/> is not NULL, the function begins by
''' extracting the icon whose resource identifier is equal to the
''' absolute value of <paramrefname="nIconIndex"/>. For example, use -3
''' to extract the icon whose resource identifier is 3.
''' </para>
''' </param>
''' <param name="phIconLarge">
''' An array of icon handles that receives handles to the large icons
''' extracted from the file. If this parameter is NULL, no large icons
''' are extracted from the file.
''' </param>
''' <param name="phIconSmall">
''' An array of icon handles that receives handles to the small icons
''' extracted from the file. If this parameter is NULL, no small icons
''' are extracted from the file.
''' </param>
''' <param name="nIcons">
''' Specifies the number of icons to extract from the file.
''' </param>
''' <returns>
''' If the <paramrefname="nIconIndex"/> parameter is -1, the
''' <paramrefname="phIconLarge"/> parameter is NULL, and the
''' <paramrefname="phiconSmall"/> parameter is NULL, then the return
''' value is the number of icons contained in the specified file.
''' Otherwise, the return value is the number of icons successfully
''' extracted from the file.
''' </returns>
<DllImport("Shell32", CharSet:=CharSet.Auto)>
Public Shared Function ExtractIconEx(<MarshalAs(UnmanagedType.LPTStr)> ByVal lpszFile As String, ByVal nIconIndex As Integer, ByVal phIconLarge As IntPtr(), ByVal phIconSmall As IntPtr(), ByVal nIcons As Integer) As Integer
End Function
<DllImport("Shell32", CharSet:=CharSet.Auto)>
Public Shared Function SHGetFileInfo(ByVal pszPath As String, ByVal dwFileAttributes As Integer, <Out> ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, ByVal uFlags As FileInfoFlags) As IntPtr
End Function
End Class
End Namespace