VSoft/Source/VSoft_Dll/Prams/ShellLink.cs
2020-11-28 15:44:33 +08:00

615 lines
21 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace VSoft.Prams
{
public class ShellLink : IDisposable
{
// Fields
private IShellLinkW linkW;
private IShellLinkA linkA;
private string shortcutFile;
// Methods
public ShellLink()
{
this.shortcutFile = "";
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
this.linkW = (IShellLinkW)new CShellLink();
}
else
{
this.linkA = (IShellLinkA)new CShellLink();
}
}
public ShellLink(string linkFile) : this()
{
this.Open(linkFile);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private bool disposed = false;
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if (disposing)
{
if (this.linkW != null)
{
Marshal.ReleaseComObject(this.linkW);
this.linkW = null;
}
if (this.linkA != null)
{
Marshal.ReleaseComObject(this.linkA);
this.linkA = null;
}
// Dispose managed resources.
this.Dispose();
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
// Note disposing has been done.
disposed = true;
}
}
~ShellLink()
{
this.Dispose(false);
}
private Icon getIcon(bool large)
{
int piIcon = 0;
StringBuilder pszIconPath = new StringBuilder(260, 260);
if (this.linkA == null)
{
this.linkW.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon);
}
else
{
this.linkA.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon);
}
string lpszFile = pszIconPath.ToString();
if (lpszFile.Length == 0)
{
FileIcon.SHGetFileInfoConstants flags = FileIcon.SHGetFileInfoConstants.SHGFI_ATTRIBUTES | FileIcon.SHGetFileInfoConstants.SHGFI_ICON;
if (large)
{
//flags = flags;
}
else
{
flags |= FileIcon.SHGetFileInfoConstants.SHGFI_SMALLICON;
}
FileIcon icon = new FileIcon(this.Target, flags);
return icon.ShellIcon;
}
IntPtr[] phIconLarge = new IntPtr[] { IntPtr.Zero };
if (large)
{
UnManagedMethods.ExtractIconEx(lpszFile, piIcon, phIconLarge, null, 1);
}
else
{
UnManagedMethods.ExtractIconEx(lpszFile, piIcon, null, phIconLarge, 1);
}
Icon icon2 = null;
if (phIconLarge[0] != IntPtr.Zero)
{
icon2 = Icon.FromHandle(phIconLarge[0]);
}
return icon2;
}
public void Open(string linkFile)
{
this.Open(linkFile, IntPtr.Zero, EShellLinkResolveFlags.SLR_ANY_MATCH | EShellLinkResolveFlags.SLR_NO_UI, 1);
}
public void Open(string linkFile, IntPtr hWnd, EShellLinkResolveFlags resolveFlags)
{
this.Open(linkFile, hWnd, resolveFlags, 1);
}
public void Open(string linkFile, IntPtr hWnd, EShellLinkResolveFlags resolveFlags, ushort timeOut)
{
uint num;
if ((resolveFlags & EShellLinkResolveFlags.SLR_NO_UI) == EShellLinkResolveFlags.SLR_NO_UI)
{
num = (uint)(resolveFlags | ((EShellLinkResolveFlags)(timeOut << 0x10)));
}
else
{
num = (uint)resolveFlags;
}
if (this.linkA == null)
{
((IPersistFile)this.linkW).Load(linkFile, 0);
this.linkW.Resolve(hWnd, num);
this.shortcutFile = linkFile;
}
else
{
((IPersistFile)this.linkA).Load(linkFile, 0);
this.linkA.Resolve(hWnd, num);
this.shortcutFile = linkFile;
}
}
public void Save()
{
this.Save(this.shortcutFile);
}
public void Save(string linkFile)
{
if (this.linkA == null)
{
((IPersistFile)this.linkW).Save(linkFile, true);
this.shortcutFile = linkFile;
}
else
{
((IPersistFile)this.linkA).Save(linkFile, true);
this.shortcutFile = linkFile;
}
}
// Properties
public string ShortCutFile
{
get =>
this.shortcutFile;
set =>
this.shortcutFile = value;
}
public Icon LargeIcon =>
this.getIcon(true);
public Icon SmallIcon =>
this.getIcon(false);
public string IconPath
{
get
{
StringBuilder pszIconPath = new StringBuilder(260, 260);
int piIcon = 0;
if (this.linkA == null)
{
this.linkW.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon);
}
else
{
this.linkA.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon);
}
return pszIconPath.ToString();
}
set
{
StringBuilder pszIconPath = new StringBuilder(260, 260);
int piIcon = 0;
if (this.linkA == null)
{
this.linkW.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon);
}
else
{
this.linkA.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon);
}
if (this.linkA == null)
{
this.linkW.SetIconLocation(value, piIcon);
}
else
{
this.linkA.SetIconLocation(value, piIcon);
}
}
}
public int IconIndex
{
get
{
StringBuilder pszIconPath = new StringBuilder(260, 260);
int piIcon = 0;
if (this.linkA == null)
{
this.linkW.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon);
return piIcon;
}
this.linkA.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon);
return piIcon;
}
set
{
StringBuilder pszIconPath = new StringBuilder(260, 260);
int piIcon = 0;
if (this.linkA == null)
{
this.linkW.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon);
}
else
{
this.linkA.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon);
}
if (this.linkA == null)
{
this.linkW.SetIconLocation(pszIconPath.ToString(), value);
}
else
{
this.linkA.SetIconLocation(pszIconPath.ToString(), value);
}
}
}
public string Target
{
get
{
StringBuilder pszFile = new StringBuilder(260, 260);
if (this.linkA == null)
{
_WIN32_FIND_DATAW pfd = new _WIN32_FIND_DATAW();
this.linkW.GetPath(pszFile, pszFile.Capacity, ref pfd, 2);
}
else
{
_WIN32_FIND_DATAA pfd = new _WIN32_FIND_DATAA();
this.linkA.GetPath(pszFile, pszFile.Capacity, ref pfd, 2);
}
return pszFile.ToString();
}
set
{
if (this.linkA == null)
{
this.linkW.SetPath(value);
}
else
{
this.linkA.SetPath(value);
}
}
}
public string WorkingDirectory
{
get
{
StringBuilder pszDir = new StringBuilder(260, 260);
if (this.linkA == null)
{
this.linkW.GetWorkingDirectory(pszDir, pszDir.Capacity);
}
else
{
this.linkA.GetWorkingDirectory(pszDir, pszDir.Capacity);
}
return pszDir.ToString();
}
set
{
if (this.linkA == null)
{
this.linkW.SetWorkingDirectory(value);
}
else
{
this.linkA.SetWorkingDirectory(value);
}
}
}
public string Description
{
get
{
StringBuilder pszFile = new StringBuilder(0x400, 0x400);
if (this.linkA == null)
{
this.linkW.GetDescription(pszFile, pszFile.Capacity);
}
else
{
this.linkA.GetDescription(pszFile, pszFile.Capacity);
}
return pszFile.ToString();
}
set
{
if (this.linkA == null)
{
this.linkW.SetDescription(value);
}
else
{
this.linkA.SetDescription(value);
}
}
}
public string Arguments
{
get
{
StringBuilder pszArgs = new StringBuilder(260, 260);
if (this.linkA == null)
{
this.linkW.GetArguments(pszArgs, pszArgs.Capacity);
}
else
{
this.linkA.GetArguments(pszArgs, pszArgs.Capacity);
}
return pszArgs.ToString();
}
set
{
if (this.linkA == null)
{
this.linkW.SetArguments(value);
}
else
{
this.linkA.SetArguments(value);
}
}
}
public LinkDisplayMode DisplayMode
{
get
{
uint piShowCmd = 0;
if (this.linkA == null)
{
this.linkW.GetShowCmd(out piShowCmd);
}
else
{
this.linkA.GetShowCmd(out piShowCmd);
}
return (LinkDisplayMode)piShowCmd;
}
set
{
if (this.linkA == null)
{
this.linkW.SetShowCmd((uint)value);
}
else
{
this.linkA.SetShowCmd((uint)value);
}
}
}
public Keys HotKey
{
get
{
short pwHotkey = 0;
if (this.linkA == null)
{
this.linkW.GetHotkey(out pwHotkey);
}
else
{
this.linkA.GetHotkey(out pwHotkey);
}
return (Keys)pwHotkey;
}
set
{
if (this.linkA == null)
{
this.linkW.SetHotkey((short)value);
}
else
{
this.linkA.SetHotkey((short)value);
}
}
}
// Nested Types
[StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct _FILETIME
{
public uint dwLowDateTime;
public uint dwHighDateTime;
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct _WIN32_FIND_DATAA
{
public uint dwFileAttributes;
public ShellLink._FILETIME ftCreationTime;
public ShellLink._FILETIME ftLastAccessTime;
public ShellLink._FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 4)]
private struct _WIN32_FIND_DATAW
{
public uint dwFileAttributes;
public ShellLink._FILETIME ftCreationTime;
public ShellLink._FILETIME ftLastAccessTime;
public ShellLink._FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
[ComImport, ClassInterface(ClassInterfaceType.None), Guid("00021401-0000-0000-C000-000000000046")]
private class CShellLink
{
}
private enum EShellLinkGP : uint
{
SLGP_SHORTPATH = 1,
SLGP_UNCPRIORITY = 2
}
[Flags]
public enum EShellLinkResolveFlags : uint
{
SLR_ANY_MATCH = 2,
SLR_INVOKE_MSI = 0x80,
SLR_NOLINKINFO = 0x40,
SLR_NO_UI = 1,
SLR_NO_UI_WITH_MSG_PUMP = 0x101,
SLR_NOUPDATE = 8,
SLR_NOSEARCH = 0x10,
SLR_NOTRACK = 0x20,
SLR_UPDATE = 4
}
[Flags]
private enum EShowWindowFlags : uint
{
SW_HIDE = 0,
SW_SHOWNORMAL = 1,
SW_NORMAL = 1,
SW_SHOWMINIMIZED = 2,
SW_SHOWMAXIMIZED = 3,
SW_MAXIMIZE = 3,
SW_SHOWNOACTIVATE = 4,
SW_SHOW = 5,
SW_MINIMIZE = 6,
SW_SHOWMINNOACTIVE = 7,
SW_SHOWNA = 8,
SW_RESTORE = 9,
SW_SHOWDEFAULT = 10,
SW_MAX = 10
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000010C-0000-0000-C000-000000000046")]
private interface IPersist
{
[PreserveSig]
void GetClassID(out Guid pClassID);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000010B-0000-0000-C000-000000000046")]
private interface IPersistFile
{
[PreserveSig]
void GetClassID(out Guid pClassID);
void IsDirty();
void Load([MarshalAs(UnmanagedType.LPWStr)] string pszFileName, uint dwMode);
void Save([MarshalAs(UnmanagedType.LPWStr)] string pszFileName, [MarshalAs(UnmanagedType.Bool)] bool fRemember);
void SaveCompleted([MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
void GetCurFile([MarshalAs(UnmanagedType.LPWStr)] out string ppszFileName);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214EE-0000-0000-C000-000000000046")]
private interface IShellLinkA
{
void GetPath([Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder pszFile, int cchMaxPath, ref ShellLink._WIN32_FIND_DATAA pfd, uint fFlags);
void GetIDList(out IntPtr ppidl);
void SetIDList(IntPtr pidl);
void GetDescription([Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder pszFile, int cchMaxName);
void SetDescription([MarshalAs(UnmanagedType.LPStr)] string pszName);
void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder pszDir, int cchMaxPath);
void SetWorkingDirectory([MarshalAs(UnmanagedType.LPStr)] string pszDir);
void GetArguments([Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder pszArgs, int cchMaxPath);
void SetArguments([MarshalAs(UnmanagedType.LPStr)] string pszArgs);
void GetHotkey(out short pwHotkey);
void SetHotkey(short pwHotkey);
void GetShowCmd(out uint piShowCmd);
void SetShowCmd(uint piShowCmd);
void GetIconLocation([Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
void SetIconLocation([MarshalAs(UnmanagedType.LPStr)] string pszIconPath, int iIcon);
void SetRelativePath([MarshalAs(UnmanagedType.LPStr)] string pszPathRel, uint dwReserved);
void Resolve(IntPtr hWnd, uint fFlags);
void SetPath([MarshalAs(UnmanagedType.LPStr)] string pszFile);
}
[ComImport, Guid("000214F9-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellLinkW
{
void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, ref ShellLink._WIN32_FIND_DATAW pfd, uint fFlags);
void GetIDList(out IntPtr ppidl);
void SetIDList(IntPtr pidl);
void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxName);
void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
void GetHotkey(out short pwHotkey);
void SetHotkey(short pwHotkey);
void GetShowCmd(out uint piShowCmd);
void SetShowCmd(uint piShowCmd);
void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved);
void Resolve(IntPtr hWnd, uint fFlags);
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
}
public enum LinkDisplayMode : uint
{
edmNormal = 1,
edmMinimized = 7,
edmMaximized = 3
}
private class UnManagedMethods
{
// Methods
[DllImport("user32")]
internal static extern int DestroyIcon(IntPtr hIcon);
[DllImport("shell32", CharSet = CharSet.Auto)]
internal static extern int ExtractIconEx([MarshalAs(UnmanagedType.LPWStr)] string lpszFile, int nIconIndex, IntPtr[] phIconLarge, IntPtr[] phIconSmall, int nIcons);
}
}
}