using IWshRuntimeLibrary;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using SystemTrayMenu.Handler;
using SystemTrayMenu.Helper;
using TAFactory.IconPack;
namespace SystemTrayMenu.Controls
{
public class RowData : IDisposable
{
public FileInfo FileInfo;
public Icon Icon;
public bool ContainsMenu;
public bool IsContextMenuOpen;
public bool ResolvedFileNotFound;
public string WorkingDirectory;
public string Arguments;
public bool IsResolvedLnk;
public string TargetFilePath;
public string Text;
public Menu SubMenu;
public int RowIndex;
public bool IsSelected;
public bool IsSelectedByKeyboard;
///
/// Loads the icon
///
/// True = directory, false = file
/// Discovered path when functions returns true
/// True when linking to a different directory, otherwise false
public bool ReadIcon(bool isDirectory, ref string resolvedLnkPath)
{
bool isLnkDirectory = false;
if (string.IsNullOrEmpty(TargetFilePath))
{
Log.Info($"TargetFilePath from {resolvedLnkPath} empty");
}
else if (isDirectory)
{
Icon = IconReader.GetFolderIcon(TargetFilePath,
IconReader.FolderType.Closed, false);
}
else
{
bool handled = false;
string fileExtension = Path.GetExtension(TargetFilePath);
if (fileExtension == ".lnk")
{
handled = SetLnk(ref isLnkDirectory,
ref resolvedLnkPath);
}
else if (fileExtension == ".url")
{
handled = SetUrl();
}
else if (fileExtension == ".sln")
{
handled = SetSln();
}
if (!handled)
{
try
{
Icon = IconReader.GetFileIconWithCache(TargetFilePath, false);
// other project -> fails sometimes
//icon = IconHelper.ExtractIcon(TargetFilePath, 0);
// standard way -> fails sometimes
//icon = Icon.ExtractAssociatedIcon(filePath);
// API Code Pack -> fails sometimes
//ShellFile shellFile = ShellFile.FromFilePath(filePath);
//Bitmap shellThumb = shellFile.Thumbnail.ExtraLargeBitmap;
}
catch (Exception ex)
{
Log.Error($"TargetFilePath:'{TargetFilePath}'", ex);
}
}
}
return isLnkDirectory;
}
private bool SetLnk(ref bool isLnkDirectory,
ref string resolvedLnkPath)
{
bool handled = false;
resolvedLnkPath = LnkHelper.ResolveShortcut(TargetFilePath);
if (LnkHelper.IsDirectory(resolvedLnkPath))
{
Icon = IconReader.GetFolderIcon(TargetFilePath,
IconReader.FolderType.Open, true);
handled = true;
isLnkDirectory = true;
}
else if (string.IsNullOrEmpty(resolvedLnkPath))
{
ResolvedFileNotFound = true;
Log.Info($"Resolve *.LNK '{TargetFilePath}' has no icon");
#warning [Feature] Resolve network root #48, start here
}
else
{
IWshShell shell = new WshShell();
var lnk = shell.CreateShortcut(TargetFilePath)
as IWshShortcut;
Arguments = lnk.Arguments;
WorkingDirectory = lnk.WorkingDirectory;
string iconLocation = lnk.IconLocation;
if (iconLocation.Length > 2)
{
iconLocation = iconLocation.Substring(0,
iconLocation.Length - 2);
if (System.IO.File.Exists(iconLocation))
{
try
{
Icon = Icon.ExtractAssociatedIcon(iconLocation);
handled = true;
}
catch (Exception ex)
{
Log.Error($"iconLocation:'{iconLocation}'", ex);
}
}
}
TargetFilePath = resolvedLnkPath;
}
SetText(Path.GetFileNameWithoutExtension(TargetFilePathOrig));
return handled;
}
private bool SetUrl()
{
bool handled = false;
string iconFile = string.Empty;
try
{
FileIni file = new FileIni(TargetFilePath);
iconFile = file.Value("IconFile", string.Empty);
if (string.IsNullOrEmpty(iconFile))
{
string browserPath = FileUrl.GetDefaultBrowserPath();
if (string.IsNullOrEmpty(browserPath))
{
Log.Info($"No default browser found!");
}
else
{
Icon = IconReader.GetFileIconWithCache(browserPath, false);
handled = true;
}
}
else if (System.IO.File.Exists(iconFile))
{
Icon = Icon.ExtractAssociatedIcon(iconFile);
handled = true;
}
else
{
Log.Info($"Resolve *.URL '{TargetFilePath}' has no icon");
}
}
catch (Exception ex)
{
Log.Error($"TargetFilePath:'{TargetFilePath}', " +
$"iconFile:'{iconFile}'", ex);
}
SetText($"{FileInfo.Name.Substring(0, FileInfo.Name.Length - 4)}");
return handled;
}
[DllImport("shell32.dll")]
static extern int FindExecutable(string lpFile, string lpDirectory, [Out] StringBuilder lpResult);
private bool SetSln()
{
bool handled = false;
var executable = new StringBuilder(1024);
try
{
FindExecutable(TargetFilePath, string.Empty, executable);
// icon = IconReader.GetFileIcon(executable, false);
// e.g. VS 2019 icon, need another icom in imagelist
List extractedIcons = IconHelper.ExtractAllIcons(
executable.ToString());
Icon = extractedIcons.Last();
handled = true;
}
catch (Exception ex)
{
Log.Error($"TargetFilePath:'{TargetFilePath}', " +
$"executable:'{executable.ToString()}'",ex);
}
return handled;
}
public void SetText(string text)
{
//text = $" {text}";
if (text.Length > MenuDefines.LengthMax)
{
text = $"{text.Substring(0, MenuDefines.LengthMax)}...";
}
Text = text;
}
#warning CodeBeauty&Refactor #49 - sort this class and check for duplicated
public event Action