initial checkin of yaulw (locally)

This commit is contained in:
Donald Duck
2016-02-15 12:32:26 -05:00
commit 857eda29e3
115 changed files with 27392 additions and 0 deletions

344
Installer/Common.cs Normal file
View File

@@ -0,0 +1,344 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Yaulw.Process;
using System.IO;
using Yaulw.Tools;
using System.Diagnostics;
using Yaulw.Other;
namespace Yaulw.Installer
{
public static class Common
{
#region Setup / Spawners
/// <summary>
/// Spawn a Setup Process (Setup.exe for example)
/// </summary>
public static void PSetupSpwan(string SetupFileNameNPath, string param_s, bool bWait)
{
try
{
if (!String.IsNullOrEmpty(SetupFileNameNPath) && Tools.PathNaming.FileNameIsValid(System.IO.Path.GetFileName(SetupFileNameNPath)))
{
//string dir = Tools.PathNaming.MakeDirectoryPathValid(System.IO.Path.GetDirectoryName(SetupFileNameNPath));
//SetupFileNameNPath = dir + System.IO.Path.DirectorySeparatorChar + System.IO.Path.GetFileName(SetupFileNameNPath);
//if (!String.IsNullOrEmpty(param_s))
//{
// CMDline cmd = new CMDline(null, null);
// bool bIsValidParse = cmd.Parse(param_s.Split(' '), false);
// if (bIsValidParse)
// param_s = cmd.MakeValidCmdStrFromNewlyParsedCmdLine();
// else
// return; // Invalid Parameters passed in that could cause OS Command Injection
//}
PStarter.StartProcess(PStartInfo.CreateProcess(SetupFileNameNPath, param_s, "", true, System.Diagnostics.ProcessWindowStyle.Hidden, false), bWait, false);
}
}
catch (Exception e) { throw e; }
}
/// <summary>
/// Spawn a Setup Process (Setup.exe for example) using shell execute
/// </summary>
public static void PSetupSpwanShell(string SetupFileNameNPath, string param_s, bool bWait)
{
try
{
if (!String.IsNullOrEmpty(SetupFileNameNPath) && Tools.PathNaming.FileNameIsValid(System.IO.Path.GetFileName(SetupFileNameNPath)))
{
//string dir = Tools.PathNaming.MakeDirectoryPathValid(System.IO.Path.GetDirectoryName(SetupFileNameNPath));
//SetupFileNameNPath = dir + System.IO.Path.DirectorySeparatorChar + System.IO.Path.GetFileName(SetupFileNameNPath);
//if (!String.IsNullOrEmpty(param_s))
//{
// CMDline cmd = new CMDline(null, null);
// bool bIsValidParse = cmd.Parse(param_s.Split(' '), false);
// if (bIsValidParse)
// param_s = cmd.MakeValidCmdStrFromNewlyParsedCmdLine();
// else
// return; // Invalid Parameters passed in that could cause OS Command Injection
//}
PStarter.StartProcess(PStartInfo.CreateProcess(SetupFileNameNPath, param_s, "", true, System.Diagnostics.ProcessWindowStyle.Hidden, true), bWait, false);
}
}
catch (Exception e) { throw e; }
}
/// <summary>
/// Spawn a MSI Setup Process (*.msi)
/// </summary>
public static void PSetupMSIEXEC(string param_s)
{
try
{
string msiexec = System.Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\msiexec.exe";
if (System.IO.File.Exists(msiexec))
{
//if (!String.IsNullOrEmpty(param_s))
//{
// CMDline cmd = new CMDline(null, null);
// bool bIsValidParse = cmd.Parse(param_s.Split(' '), false);
// if (bIsValidParse)
// param_s = cmd.MakeValidCmdStrFromNewlyParsedCmdLine();
// else
// return; // Invalid Parameters passed in that could cause OS Command Injection
//}
PStarter.StartProcess(PStartInfo.CreateProcess(msiexec, param_s, "", true, System.Diagnostics.ProcessWindowStyle.Hidden, false), true, false);
}
}
catch (Exception e) { throw e; }
}
/// <summary>
/// Run a command on the commandline * Hidden *
/// </summary>
/// <param name="cmdline">cmd to run</param>
public static string RunCmdLine(string cmdline)
{
string result = PStarter.RunDosCommand(cmdline);
return result;
}
#endregion
#region Service (ServiceW Repeat with Check Existence)
/// <summary>
/// Stop a service
/// </summary>
/// <param name="ServiceName">name of service to stop</param>
/// <returns>true if successful, false otherwise</returns>
public static bool StopService(string ServiceName)
{
bool bSuccess = true;
if (ServiceW.DoesServiceExist(ServiceName))
bSuccess = ServiceW.StopService(ServiceName, true, 120);
return bSuccess;
}
/// <summary>
/// Stop a service
/// </summary>
/// <param name="ServiceName">name of service to stop</param>
/// <returns>true if successful, false otherwise</returns>
public static bool StopService(string ServiceName, int nTimeoutBeforeKill)
{
bool bSuccess = true;
if (ServiceW.DoesServiceExist(ServiceName))
bSuccess = ServiceW.StopService(ServiceName, true, nTimeoutBeforeKill);
return bSuccess;
}
/// <summary>
/// start a service
/// </summary>
/// <param name="ServiceName">name of a service to start</param>
/// <returns>true if successful, false otherwise</returns>
public static bool StartService(string ServiceName)
{
bool bSuccess = true;
if (ServiceW.DoesServiceExist(ServiceName))
bSuccess = ServiceW.StartService(ServiceName, 120);
return bSuccess;
}
/// <summary>
/// Does Service Exist
/// </summary>
/// <param name="ServiceName">Name of service to check</param>
/// <returns>true if successful, false otherwise</returns>
public static bool ServiceExists(string ServiceName)
{
return ServiceW.DoesServiceExist(ServiceName);
}
#endregion
#region Windows Utils
/// <summary>
/// Use this to get the complete path to a .net framework utility like gacutil.exe or
/// installutil.exe.. any .net framework utility. Will fall back to look in the %temp% folder,
/// if not found, giving the opportunity to deploy the util directly with the components
/// </summary>
/// <param name="UtilFileName">the utility in .net you are looking for like gacutil.exe</param>
/// <returns>the full filenameNpath or "", if no existing file found</returns>
public static string GetNetFrameworkUtilFileNameNPathFile(string UtilFileName)
{
string windir = System.Environment.GetEnvironmentVariable("windir", EnvironmentVariableTarget.Machine);
string NetFramework1_0 = windir + "\\Microsoft.Net\\Framework\\v1.0.3705";
string NetFramework1_1 = windir + "\\Microsoft.Net\\Framework\\v1.1.4322";
string NetFramework2_0 = windir + "\\Microsoft.Net\\Framework\\v2.0.50727";
string NetFramework3_0 = windir + "\\Microsoft.Net\\Framework\\v3.0";
string NetFramework3_5 = windir + "\\Microsoft.Net\\Framework\\v3.5";
string NetFramework4_0 = windir + "\\Microsoft.Net\\Framework\\v4.0.30319";
string TempPath = PathNaming.PathEndsWithNoSlash(Path.GetTempPath()); // We use this as a Fallback, in case file doesn't exist in the framework
string[] Frameworks = new string[] { NetFramework2_0, NetFramework4_0, NetFramework1_0, NetFramework1_1, NetFramework3_0, NetFramework3_5, TempPath };
string NetUtilFileNameNPath = "";
foreach (string framework in Frameworks)
{
if (System.IO.File.Exists(framework + "\\" + UtilFileName))
{
NetUtilFileNameNPath = framework + "\\" + UtilFileName;
return NetUtilFileNameNPath;
}
};
return NetUtilFileNameNPath;
}
/// <summary>
/// Quick Helper to get the Program Files Path for the specific system
/// </summary>
/// <returns>Program Files path with a '/' at the end</returns>
public static string GetProgramFilesPathOnSystemWithEndSlash()
{
string ProgramFiles = System.Environment.GetEnvironmentVariable("ProgramFiles(x86)");
if (String.IsNullOrEmpty(ProgramFiles))
ProgramFiles = System.Environment.GetEnvironmentVariable("ProgramFiles");
return PathNaming.PathEndsWithSlash(ProgramFiles);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static string SetOwnership()
{
// in order to do any of this, sadly, we must first install the windows resource kit
//subinacl /subdirectories *.* /setowner=domainname\user
return String.Empty;
}
/// <summary>
/// To grant the specified User or group Full Control permissions to the folder and its contents
/// </summary>
/// <param name="FolderNPath">full path to folder/directory</param>
/// <param name="UserOrGroup">domainname\administrator, any windows user or group</param>
/// <returns></returns>
public static bool GrantFullPermissionToFolderForUserOrGroup(string FolderNPath, string UserOrGroup)
{
if (Directory.Exists(FolderNPath))
{
string command = String.Format("cacls \"{0}\" /t /e /g {1}:f", FolderNPath, UserOrGroup);
if (command.Contains("Invalid arguments."))
return false;
else
return true;
}
return false;
}
#endregion
#region Windows Commands
/// <summary>
/// Get The System up Time, important because we need SQL Server and Advantage up and running before
/// doing anything
/// </summary>
/// <returns></returns>
public static TimeSpan GetSystemUpTime()
{
string Result = Yaulw.Installer.Common.RunCmdLine("net statistics server");
int n = Result.IndexOf("Sessions accepted");
if (n != -1)
{
Result = Result.Substring(0, n);
n = Result.IndexOf("Statistics since ");
if (n != -1)
{
Result = Result.Substring(n + "Statistics since ".Length);
Result = Result.Replace("\n", "");
Result = Result.Replace("\r", "");
DateTime BootTime;
if (DateTime.TryParse(Result, out BootTime))
return (DateTime.Now - BootTime);
}
}
// Something went wrong with the first approach,
// let's try another...
using (var uptime = new PerformanceCounter("System", "System Up Time"))
{
uptime.NextValue(); //Call this an extra time before reading its value
return TimeSpan.FromSeconds(uptime.NextValue());
}
}
/// <summary>
/// Use this to create a quick File Shortcut on the system using ShellLink (File Only)
/// </summary>
/// <param name="TargetFileNameNPath">A valid File on the system to point to (not a url) i believe url's are created differently</param>
/// <param name="LnkFileNameNPath">a valid .lnk file name and location where to put the shortcut</param>
public static void CreateFileShortcut(string TargetFileNameNPath, string LnkFileNameNPath)
{
if (String.IsNullOrEmpty(TargetFileNameNPath) || String.IsNullOrEmpty(LnkFileNameNPath))
return;
if (!System.IO.File.Exists(TargetFileNameNPath))
return;
if (System.IO.File.Exists(LnkFileNameNPath))
System.IO.File.Delete(LnkFileNameNPath);
using (ShellLink shortcut = new ShellLink())
{
shortcut.Target = TargetFileNameNPath;
shortcut.WorkingDirectory = Path.GetDirectoryName(TargetFileNameNPath);
shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
shortcut.Description = ""; // doesn't appear to do anything
shortcut.Save(LnkFileNameNPath);
}
}
#endregion
#region Resource Extraction
/// <summary>
/// Extract a Binary Resource from a stream and write it to a file
/// </summary>
/// <param name="resourceStream"></param>
/// <param name="FileNameNPath"></param>
/// <param name="bForceWrite"></param>
/// <returns></returns>
public static bool ExtractResourceStreamToFile(Stream resourceStream, string FileNameNPath, bool bForceWrite)
{
if (resourceStream != null && !String.IsNullOrEmpty(FileNameNPath))
{
if (bForceWrite || !System.IO.File.Exists(FileNameNPath))
{
try
{
using (resourceStream)
using (BinaryReader br = new BinaryReader(resourceStream))
using (BinaryWriter bw = new BinaryWriter(new FileStream(FileNameNPath, FileMode.Create)))
{
byte[] buffer = new byte[64 * 1024];
int numread = br.Read(buffer, 0, buffer.Length);
while (numread > 0)
{
bw.Write(buffer, 0, numread);
numread = br.Read(buffer, 0, buffer.Length);
}
bw.Flush();
}
return true;
}
catch (Exception) { /* ignore */ }
}
}
return false;
}
#endregion
}
}

249
Installer/FileIcon.cs Normal file
View File

@@ -0,0 +1,249 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
namespace Yaulw.Installer
{
/// <summary>
/// Enables extraction of icons for any file type from
/// the Shell.
/// </summary>
/// <seealso cref="http://www.vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects/Creating_and_Modifying_Shortcuts/ShellLink_Code_zip_ShellLink/FileIcon_cs.asp"/>
public class FileIcon
{
#region UnmanagedCode
private const int MAX_PATH = 260;
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public int dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
[DllImport("shell32")]
private static extern int SHGetFileInfo(
string pszPath,
int dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags);
[DllImport("user32.dll")]
private static extern int DestroyIcon(IntPtr hIcon);
private const int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x100;
private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x2000;
private const int FORMAT_MESSAGE_FROM_HMODULE = 0x800;
private const int FORMAT_MESSAGE_FROM_STRING = 0x400;
private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x200;
private const int FORMAT_MESSAGE_MAX_WIDTH_MASK = 0xFF;
[DllImport("kernel32")]
private extern static int FormatMessage(
int dwFlags,
IntPtr lpSource,
int dwMessageId,
int dwLanguageId,
string lpBuffer,
uint nSize,
int argumentsLong);
[DllImport("kernel32")]
private extern static int GetLastError();
#endregion
#region Member Variables
private string fileName;
private string displayName;
private string typeName;
private SHGetFileInfoConstants flags;
private Icon fileIcon;
#endregion
#region Enumerations
[Flags]
public enum SHGetFileInfoConstants : int
{
SHGFI_ICON = 0x100, // get icon
SHGFI_DISPLAYNAME = 0x200, // get display name
SHGFI_TYPENAME = 0x400, // get type name
SHGFI_ATTRIBUTES = 0x800, // get attributes
SHGFI_ICONLOCATION = 0x1000, // get icon location
SHGFI_EXETYPE = 0x2000, // return exe type
SHGFI_SYSICONINDEX = 0x4000, // get system icon index
SHGFI_LINKOVERLAY = 0x8000, // put a link overlay on icon
SHGFI_SELECTED = 0x10000, // show icon in selected state
SHGFI_ATTR_SPECIFIED = 0x20000, // get only specified attributes
SHGFI_LARGEICON = 0x0, // get large icon
SHGFI_SMALLICON = 0x1, // get small icon
SHGFI_OPENICON = 0x2, // get open icon
SHGFI_SHELLICONSIZE = 0x4, // get shell size icon
//SHGFI_PIDL = 0x8, // pszPath is a pidl
SHGFI_USEFILEATTRIBUTES = 0x10, // use passed dwFileAttribute
SHGFI_ADDOVERLAYS = 0x000000020, // apply the appropriate overlays
SHGFI_OVERLAYINDEX = 0x000000040 // Get the index of the overlay
}
#endregion
#region Implementation
/// <summary>
/// Gets/sets the flags used to extract the icon
/// </summary>
public FileIcon.SHGetFileInfoConstants Flags
{
get
{
return flags;
}
set
{
flags = value;
}
}
/// <summary>
/// Gets/sets the filename to get the icon for
/// </summary>
public string FileName
{
get
{
return fileName;
}
set
{
fileName = value;
}
}
/// <summary>
/// Gets the icon for the chosen file
/// </summary>
public Icon ShellIcon
{
get
{
return fileIcon;
}
}
/// <summary>
/// Gets the display name for the selected file
/// if the SHGFI_DISPLAYNAME flag was set.
/// </summary>
public string DisplayName
{
get
{
return displayName;
}
}
/// <summary>
/// Gets the type name for the selected file
/// if the SHGFI_TYPENAME flag was set.
/// </summary>
public string TypeName
{
get
{
return typeName;
}
}
/// <summary>
/// Gets the information for the specified
/// file name and flags.
/// </summary>
public void GetInfo()
{
fileIcon = null;
typeName = "";
displayName = "";
SHFILEINFO shfi = new SHFILEINFO();
uint shfiSize = (uint)Marshal.SizeOf(shfi.GetType());
int ret = SHGetFileInfo(
fileName, 0, ref shfi, shfiSize, (uint)(flags));
if (ret != 0)
{
if (shfi.hIcon != IntPtr.Zero)
{
fileIcon = System.Drawing.Icon.FromHandle(shfi.hIcon);
// Now owned by the GDI+ object
//DestroyIcon(shfi.hIcon);
}
typeName = shfi.szTypeName;
displayName = shfi.szDisplayName;
}
else
{
int err = GetLastError();
Console.WriteLine("Error {0}", err);
string txtS = new string('\0', 256);
int len = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
IntPtr.Zero, err, 0, txtS, 256, 0);
Console.WriteLine("Len {0} text {1}", len, txtS);
// throw exception
}
}
/// <summary>
/// Constructs a new, default instance of the FileIcon
/// class. Specify the filename and call GetInfo()
/// to retrieve an icon.
/// </summary>
public FileIcon()
{
flags = SHGetFileInfoConstants.SHGFI_ICON |
SHGetFileInfoConstants.SHGFI_DISPLAYNAME |
SHGetFileInfoConstants.SHGFI_TYPENAME |
SHGetFileInfoConstants.SHGFI_ATTRIBUTES |
SHGetFileInfoConstants.SHGFI_EXETYPE;
}
/// <summary>
/// Constructs a new instance of the FileIcon class
/// and retrieves the icon, display name and type name
/// for the specified file.
/// </summary>
/// <param name="fileName">The filename to get the icon,
/// display name and type name for</param>
public FileIcon(string fileName)
: this()
{
this.fileName = fileName;
GetInfo();
}
/// <summary>
/// Constructs a new instance of the FileIcon class
/// and retrieves the information specified in the
/// flags.
/// </summary>
/// <param name="fileName">The filename to get information
/// for</param>
/// <param name="flags">The flags to use when extracting the
/// icon and other shell information.</param>
public FileIcon(string fileName, FileIcon.SHGetFileInfoConstants flags)
{
this.fileName = fileName;
this.flags = flags;
GetInfo();
}
#endregion
}
}

953
Installer/ShellLink.cs Normal file
View File

@@ -0,0 +1,953 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Yaulw.Installer
{
#region ShellLink Object
/// <summary>
/// Summary description for ShellLink.
/// </summary>
/// <seealso cref="http://www.vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects/Creating_and_Modifying_Shortcuts/ShellLink_Code_zip_ShellLink/ShellLink_cs.asp"/>
public class ShellLink : IDisposable
{
#region ComInterop for IShellLink
#region IPersist Interface
[ComImportAttribute()]
[GuidAttribute("0000010C-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IPersist
{
[PreserveSig]
//[helpstring("Returns the class identifier for the component object")]
void GetClassID(out Guid pClassID);
}
#endregion
#region IPersistFile Interface
[ComImportAttribute()]
[GuidAttribute("0000010B-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IPersistFile
{
// can't get this to go if I extend IPersist, so put it here:
[PreserveSig]
void GetClassID(out Guid pClassID);
//[helpstring("Checks for changes since last file write")]
void IsDirty();
//[helpstring("Opens the specified file and initializes the object from its contents")]
void Load(
[MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
uint dwMode);
//[helpstring("Saves the object into the specified file")]
void Save(
[MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
[MarshalAs(UnmanagedType.Bool)] bool fRemember);
//[helpstring("Notifies the object that save is completed")]
void SaveCompleted(
[MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
//[helpstring("Gets the current name of the file associated with the object")]
void GetCurFile(
[MarshalAs(UnmanagedType.LPWStr)] out string ppszFileName);
}
#endregion
#region IShellLink Interface
[ComImportAttribute()]
[GuidAttribute("000214EE-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellLinkA
{
//[helpstring("Retrieves the path and filename of a shell link object")]
void GetPath(
[Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszFile,
int cchMaxPath,
ref _WIN32_FIND_DATAA pfd,
uint fFlags);
//[helpstring("Retrieves the list of shell link item identifiers")]
void GetIDList(out IntPtr ppidl);
//[helpstring("Sets the list of shell link item identifiers")]
void SetIDList(IntPtr pidl);
//[helpstring("Retrieves the shell link description string")]
void GetDescription(
[Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszFile,
int cchMaxName);
//[helpstring("Sets the shell link description string")]
void SetDescription(
[MarshalAs(UnmanagedType.LPStr)] string pszName);
//[helpstring("Retrieves the name of the shell link working directory")]
void GetWorkingDirectory(
[Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszDir,
int cchMaxPath);
//[helpstring("Sets the name of the shell link working directory")]
void SetWorkingDirectory(
[MarshalAs(UnmanagedType.LPStr)] string pszDir);
//[helpstring("Retrieves the shell link command-line arguments")]
void GetArguments(
[Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszArgs,
int cchMaxPath);
//[helpstring("Sets the shell link command-line arguments")]
void SetArguments(
[MarshalAs(UnmanagedType.LPStr)] string pszArgs);
//[propget, helpstring("Retrieves or sets the shell link hot key")]
void GetHotkey(out short pwHotkey);
//[propput, helpstring("Retrieves or sets the shell link hot key")]
void SetHotkey(short pwHotkey);
//[propget, helpstring("Retrieves or sets the shell link show command")]
void GetShowCmd(out uint piShowCmd);
//[propput, helpstring("Retrieves or sets the shell link show command")]
void SetShowCmd(uint piShowCmd);
//[helpstring("Retrieves the location (path and index) of the shell link icon")]
void GetIconLocation(
[Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszIconPath,
int cchIconPath,
out int piIcon);
//[helpstring("Sets the location (path and index) of the shell link icon")]
void SetIconLocation(
[MarshalAs(UnmanagedType.LPStr)] string pszIconPath,
int iIcon);
//[helpstring("Sets the shell link relative path")]
void SetRelativePath(
[MarshalAs(UnmanagedType.LPStr)] string pszPathRel,
uint dwReserved);
//[helpstring("Resolves a shell link. The system searches for the shell link object and updates the shell link path and its list of identifiers (if necessary)")]
void Resolve(
IntPtr hWnd,
uint fFlags);
//[helpstring("Sets the shell link path and filename")]
void SetPath(
[MarshalAs(UnmanagedType.LPStr)] string pszFile);
}
[ComImportAttribute()]
[GuidAttribute("000214F9-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellLinkW
{
//[helpstring("Retrieves the path and filename of a shell link object")]
void GetPath(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile,
int cchMaxPath,
ref _WIN32_FIND_DATAW pfd,
uint fFlags);
//[helpstring("Retrieves the list of shell link item identifiers")]
void GetIDList(out IntPtr ppidl);
//[helpstring("Sets the list of shell link item identifiers")]
void SetIDList(IntPtr pidl);
//[helpstring("Retrieves the shell link description string")]
void GetDescription(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile,
int cchMaxName);
//[helpstring("Sets the shell link description string")]
void SetDescription(
[MarshalAs(UnmanagedType.LPWStr)] string pszName);
//[helpstring("Retrieves the name of the shell link working directory")]
void GetWorkingDirectory(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir,
int cchMaxPath);
//[helpstring("Sets the name of the shell link working directory")]
void SetWorkingDirectory(
[MarshalAs(UnmanagedType.LPWStr)] string pszDir);
//[helpstring("Retrieves the shell link command-line arguments")]
void GetArguments(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs,
int cchMaxPath);
//[helpstring("Sets the shell link command-line arguments")]
void SetArguments(
[MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
//[propget, helpstring("Retrieves or sets the shell link hot key")]
void GetHotkey(out short pwHotkey);
//[propput, helpstring("Retrieves or sets the shell link hot key")]
void SetHotkey(short pwHotkey);
//[propget, helpstring("Retrieves or sets the shell link show command")]
void GetShowCmd(out uint piShowCmd);
//[propput, helpstring("Retrieves or sets the shell link show command")]
void SetShowCmd(uint piShowCmd);
//[helpstring("Retrieves the location (path and index) of the shell link icon")]
void GetIconLocation(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
int cchIconPath,
out int piIcon);
//[helpstring("Sets the location (path and index) of the shell link icon")]
void SetIconLocation(
[MarshalAs(UnmanagedType.LPWStr)] string pszIconPath,
int iIcon);
//[helpstring("Sets the shell link relative path")]
void SetRelativePath(
[MarshalAs(UnmanagedType.LPWStr)] string pszPathRel,
uint dwReserved);
//[helpstring("Resolves a shell link. The system searches for the shell link object and updates the shell link path and its list of identifiers (if necessary)")]
void Resolve(
IntPtr hWnd,
uint fFlags);
//[helpstring("Sets the shell link path and filename")]
void SetPath(
[MarshalAs(UnmanagedType.LPWStr)] string pszFile);
}
#endregion
#region ShellLinkCoClass
[GuidAttribute("00021401-0000-0000-C000-000000000046")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComImportAttribute()]
private class CShellLink{}
#endregion
#region Private IShellLink enumerations
private enum EShellLinkGP : uint
{
SLGP_SHORTPATH = 1,
SLGP_UNCPRIORITY = 2
}
[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
}
#endregion
#region IShellLink Private structs
[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0,
CharSet=CharSet.Unicode)]
private struct _WIN32_FIND_DATAW
{
public uint dwFileAttributes;
public _FILETIME ftCreationTime;
public _FILETIME ftLastAccessTime;
public _FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 260)] // MAX_PATH
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0,
CharSet=CharSet.Ansi)]
private struct _WIN32_FIND_DATAA
{
public uint dwFileAttributes;
public _FILETIME ftCreationTime;
public _FILETIME ftLastAccessTime;
public _FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 260)] // MAX_PATH
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0)]
private struct _FILETIME
{
public uint dwLowDateTime;
public uint dwHighDateTime;
}
#endregion
#region UnManaged Methods
private class UnManagedMethods
{
[DllImport("Shell32", CharSet=CharSet.Auto)]
internal extern static int ExtractIconEx (
[MarshalAs(UnmanagedType.LPTStr)]
string lpszFile,
int nIconIndex,
IntPtr[] phIconLarge,
IntPtr[] phIconSmall,
int nIcons);
[DllImport("user32")]
internal static extern int DestroyIcon(IntPtr hIcon);
}
#endregion
#endregion
#region Enumerations
/// <summary>
/// Flags determining how the links with missing
/// targets are resolved.
/// </summary>
[Flags]
public enum EShellLinkResolveFlags : uint
{
/// <summary>
/// Allow any match during resolution. Has no effect
/// on ME/2000 or above, use the other flags instead.
/// </summary>
SLR_ANY_MATCH = 0x2,
/// <summary>
/// Call the Microsoft Windows Installer.
/// </summary>
SLR_INVOKE_MSI = 0x80,
/// <summary>
/// Disable distributed link tracking. By default,
/// distributed link tracking tracks removable media
/// across multiple devices based on the volume name.
/// It also uses the UNC path to track remote file
/// systems whose drive letter has changed. Setting
/// SLR_NOLINKINFO disables both types of tracking.
/// </summary>
SLR_NOLINKINFO = 0x40,
/// <summary>
/// Do not display a dialog box if the link cannot be resolved.
/// When SLR_NO_UI is set, a time-out value that specifies the
/// maximum amount of time to be spent resolving the link can
/// be specified in milliseconds. The function returns if the
/// link cannot be resolved within the time-out duration.
/// If the timeout is not set, the time-out duration will be
/// set to the default value of 3,000 milliseconds (3 seconds).
/// </summary>
SLR_NO_UI = 0x1,
/// <summary>
/// Not documented in SDK. Assume same as SLR_NO_UI but
/// intended for applications without a hWnd.
/// </summary>
SLR_NO_UI_WITH_MSG_PUMP = 0x101,
/// <summary>
/// Do not update the link information.
/// </summary>
SLR_NOUPDATE = 0x8,
/// <summary>
/// Do not execute the search heuristics.
/// </summary>
SLR_NOSEARCH = 0x10,
/// <summary>
/// Do not use distributed link tracking.
/// </summary>
SLR_NOTRACK = 0x20,
/// <summary>
/// If the link object has changed, update its path and list
/// of identifiers. If SLR_UPDATE is set, you do not need to
/// call IPersistFile::IsDirty to determine whether or not
/// the link object has changed.
/// </summary>
SLR_UPDATE = 0x4
}
public enum LinkDisplayMode : uint
{
edmNormal = EShowWindowFlags.SW_NORMAL,
edmMinimized = EShowWindowFlags.SW_SHOWMINNOACTIVE,
edmMaximized = EShowWindowFlags.SW_MAXIMIZE
}
#endregion
#region Member Variables
// Use Unicode (W) under NT, otherwise use ANSI
private IShellLinkW linkW;
private IShellLinkA linkA;
private string shortcutFile = "";
#endregion
#region Constructor
/// <summary>
/// Creates an instance of the Shell Link object.
/// </summary>
public ShellLink()
{
if (System.Environment.OSVersion.Platform == PlatformID.Win32NT)
{
linkW = (IShellLinkW)new CShellLink();
}
else
{
linkA = (IShellLinkA)new CShellLink();
}
}
/// <summary>
/// Creates an instance of a Shell Link object
/// from the specified link file
/// </summary>
/// <param name="linkFile">The Shortcut file to open</param>
public ShellLink(string linkFile) : this()
{
Open(linkFile);
}
#endregion
#region Destructor and Dispose
/// <summary>
/// Call dispose just in case it hasn't happened yet
/// </summary>
~ShellLink()
{
Dispose();
}
/// <summary>
/// Dispose the object, releasing the COM ShellLink object
/// </summary>
public void Dispose()
{
if (linkW != null )
{
Marshal.ReleaseComObject(linkW);
linkW = null;
}
if (linkA != null)
{
Marshal.ReleaseComObject(linkA);
linkA = null;
}
}
#endregion
#region Implementation
public string ShortCutFile
{
get
{
return this.shortcutFile;
}
set
{
this.shortcutFile = value;
}
}
/// <summary>
/// Gets a System.Drawing.Icon containing the icon for this
/// ShellLink object.
/// </summary>
public Icon LargeIcon
{
get
{
return getIcon(true);
}
}
public Icon SmallIcon
{
get
{
return getIcon(false);
}
}
private Icon getIcon(bool large)
{
// Get icon index and path:
int iconIndex = 0;
StringBuilder iconPath = new StringBuilder(260, 260);
if (linkA == null)
{
linkW.GetIconLocation(iconPath, iconPath.Capacity, out iconIndex);
}
else
{
linkA.GetIconLocation(iconPath, iconPath.Capacity, out iconIndex);
}
string iconFile = iconPath.ToString();
// If there are no details set for the icon, then we must use
// the shell to get the icon for the target:
if (iconFile.Length == 0)
{
// Use the FileIcon object to get the icon:
FileIcon.SHGetFileInfoConstants flags =
FileIcon.SHGetFileInfoConstants.SHGFI_ICON |
FileIcon.SHGetFileInfoConstants.SHGFI_ATTRIBUTES;
if (large)
{
flags = flags | FileIcon.SHGetFileInfoConstants.SHGFI_LARGEICON;
}
else
{
flags = flags | FileIcon.SHGetFileInfoConstants.SHGFI_SMALLICON;
}
FileIcon fileIcon = new FileIcon(Target, flags);
return fileIcon.ShellIcon;
}
else
{
// Use ExtractIconEx to get the icon:
IntPtr[] hIconEx = new IntPtr[1] {IntPtr.Zero};
int iconCount = 0;
if (large)
{
iconCount = UnManagedMethods.ExtractIconEx(
iconFile,
iconIndex,
hIconEx,
null,
1);
}
else
{
iconCount = UnManagedMethods.ExtractIconEx(
iconFile,
iconIndex,
null,
hIconEx,
1);
}
// If success then return as a GDI+ object
Icon icon = null;
if (hIconEx[0] != IntPtr.Zero)
{
icon = Icon.FromHandle(hIconEx[0]);
//UnManagedMethods.DestroyIcon(hIconEx[0]);
}
return icon;
}
}
/// <summary>
/// Gets the path to the file containing the icon for this shortcut.
/// </summary>
public string IconPath
{
get
{
StringBuilder iconPath = new StringBuilder(260, 260);
int iconIndex = 0;
if (linkA == null)
{
linkW.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
else
{
linkA.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
return iconPath.ToString();
}
set
{
StringBuilder iconPath = new StringBuilder(260, 260);
int iconIndex = 0;
if (linkA == null)
{
linkW.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
else
{
linkA.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
if (linkA == null)
{
linkW.SetIconLocation(value, iconIndex);
}
else
{
linkA.SetIconLocation(value, iconIndex);
}
}
}
/// <summary>
/// Gets the index of this icon within the icon path's resources
/// </summary>
public int IconIndex
{
get
{
StringBuilder iconPath = new StringBuilder(260, 260);
int iconIndex = 0;
if (linkA == null)
{
linkW.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
else
{
linkA.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
return iconIndex;
}
set
{
StringBuilder iconPath = new StringBuilder(260, 260);
int iconIndex = 0;
if (linkA == null)
{
linkW.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
else
{
linkA.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
if (linkA == null)
{
linkW.SetIconLocation(iconPath.ToString(), value);
}
else
{
linkA.SetIconLocation(iconPath.ToString(), value);
}
}
}
/// <summary>
/// Gets/sets the fully qualified path to the link's target
/// </summary>
public string Target
{
get
{
StringBuilder target = new StringBuilder(260, 260);
if (linkA == null)
{
_WIN32_FIND_DATAW fd = new _WIN32_FIND_DATAW();
linkW.GetPath(target, target.Capacity, ref fd,
(uint)EShellLinkGP.SLGP_UNCPRIORITY);
}
else
{
_WIN32_FIND_DATAA fd = new _WIN32_FIND_DATAA();
linkA.GetPath(target, target.Capacity, ref fd,
(uint)EShellLinkGP.SLGP_UNCPRIORITY);
}
return target.ToString();
}
set
{
if (linkA == null)
{
linkW.SetPath(value);
}
else
{
linkA.SetPath(value);
}
}
}
/// <summary>
/// Gets/sets the Working Directory for the Link
/// </summary>
public string WorkingDirectory
{
get
{
StringBuilder path = new StringBuilder(260, 260);
if (linkA == null)
{
linkW.GetWorkingDirectory(path, path.Capacity);
}
else
{
linkA.GetWorkingDirectory(path, path.Capacity);
}
return path.ToString();
}
set
{
if (linkA == null)
{
linkW.SetWorkingDirectory(value);
}
else
{
linkA.SetWorkingDirectory(value);
}
}
}
/// <summary>
/// Gets/sets the description of the link
/// </summary>
public string Description
{
get
{
StringBuilder description = new StringBuilder(1024, 1024);
if (linkA == null)
{
linkW.GetDescription(description, description.Capacity);
}
else
{
linkA.GetDescription(description, description.Capacity);
}
return description.ToString();
}
set
{
if (linkA == null)
{
linkW.SetDescription(value);
}
else
{
linkA.SetDescription(value);
}
}
}
/// <summary>
/// Gets/sets any command line arguments associated with the link
/// </summary>
public string Arguments
{
get
{
StringBuilder arguments = new StringBuilder(260, 260);
if (linkA == null)
{
linkW.GetArguments(arguments, arguments.Capacity);
}
else
{
linkA.GetArguments(arguments, arguments.Capacity);
}
return arguments.ToString();
}
set
{
if (linkA == null)
{
linkW.SetArguments(value);
}
else
{
linkA.SetArguments(value);
}
}
}
/// <summary>
/// Gets/sets the initial display mode when the shortcut is
/// run
/// </summary>
public LinkDisplayMode DisplayMode
{
get
{
uint cmd = 0;
if (linkA == null)
{
linkW.GetShowCmd(out cmd);
}
else
{
linkA.GetShowCmd(out cmd);
}
return (LinkDisplayMode)cmd;
}
set
{
if (linkA == null)
{
linkW.SetShowCmd((uint)value);
}
else
{
linkA.SetShowCmd((uint)value);
}
}
}
/// <summary>
/// Gets/sets the HotKey to start the shortcut (if any)
/// </summary>
public Keys HotKey
{
get
{
short key = 0;
if (linkA == null)
{
linkW.GetHotkey(out key);
}
else
{
linkA.GetHotkey(out key);
}
return (Keys)key;
}
set
{
if (linkA == null)
{
linkW.SetHotkey((short)value);
}
else
{
linkA.SetHotkey((short)value);
}
}
}
/// <summary>
/// Saves the shortcut to ShortCutFile.
/// </summary>
public void Save()
{
Save(shortcutFile);
}
/// <summary>
/// Saves the shortcut to the specified file
/// </summary>
/// <param name="linkFile">The shortcut file (.lnk)</param>
public void Save(
string linkFile
)
{
// Save the object to disk
if (linkA == null)
{
((IPersistFile)linkW).Save(linkFile, true);
shortcutFile = linkFile;
}
else
{
((IPersistFile)linkA).Save(linkFile, true);
shortcutFile = linkFile;
}
}
/// <summary>
/// Loads a shortcut from the specified file
/// </summary>
/// <param name="linkFile">The shortcut file (.lnk) to load</param>
public void Open(
string linkFile
)
{
Open(linkFile,
IntPtr.Zero,
(EShellLinkResolveFlags.SLR_ANY_MATCH |
EShellLinkResolveFlags.SLR_NO_UI),
1);
}
/// <summary>
/// Loads a shortcut from the specified file, and allows flags controlling
/// the UI behaviour if the shortcut's target isn't found to be set.
/// </summary>
/// <param name="linkFile">The shortcut file (.lnk) to load</param>
/// <param name="hWnd">The window handle of the application's UI, if any</param>
/// <param name="resolveFlags">Flags controlling resolution behaviour</param>
public void Open(
string linkFile,
IntPtr hWnd,
EShellLinkResolveFlags resolveFlags
)
{
Open(linkFile,
hWnd,
resolveFlags,
1);
}
/// <summary>
/// Loads a shortcut from the specified file, and allows flags controlling
/// the UI behaviour if the shortcut's target isn't found to be set. If
/// no SLR_NO_UI is specified, you can also specify a timeout.
/// </summary>
/// <param name="linkFile">The shortcut file (.lnk) to load</param>
/// <param name="hWnd">The window handle of the application's UI, if any</param>
/// <param name="resolveFlags">Flags controlling resolution behaviour</param>
/// <param name="timeOut">Timeout if SLR_NO_UI is specified, in ms.</param>
public void Open(
string linkFile,
IntPtr hWnd,
EShellLinkResolveFlags resolveFlags,
ushort timeOut
)
{
uint flags;
if ((resolveFlags & EShellLinkResolveFlags.SLR_NO_UI)
== EShellLinkResolveFlags.SLR_NO_UI)
{
flags = (uint)((int)resolveFlags | (timeOut << 16));
}
else
{
flags = (uint)resolveFlags;
}
if (linkA == null)
{
((IPersistFile)linkW).Load(linkFile, 0); //STGM_DIRECT)
linkW.Resolve(hWnd, flags);
this.shortcutFile = linkFile;
}
else
{
((IPersistFile)linkA).Load(linkFile, 0); //STGM_DIRECT)
linkA.Resolve(hWnd, flags);
this.shortcutFile = linkFile;
}
}
#endregion
}
#endregion
}