1
0

Auto-commit: 2025-10-31 08:58:35

This commit is contained in:
David Wuibaille
2025-10-31 08:58:36 +01:00
parent 7d94414992
commit 7cc3011354
1088 changed files with 193455 additions and 0 deletions

View File

@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pinto10v2", "Pinto10v2\Pinto10v2.csproj", "{94C44A31-BA4C-47A3-A6FC-D7CBAACF2A31}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{94C44A31-BA4C-47A3-A6FC-D7CBAACF2A31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94C44A31-BA4C-47A3-A6FC-D7CBAACF2A31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94C44A31-BA4C-47A3-A6FC-D7CBAACF2A31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94C44A31-BA4C-47A3-A6FC-D7CBAACF2A31}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>

View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{94C44A31-BA4C-47A3-A6FC-D7CBAACF2A31}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PinTo10v2</RootNamespace>
<AssemblyName>PinTo10v2</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<StartupObject>PinTo10v2.Program</StartupObject>
</PropertyGroup>
<PropertyGroup>
<NoWin32Manifest>true</NoWin32Manifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ShellLink.cs" />
<Compile Include="Utils.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<COMReference Include="IWshRuntimeLibrary">
<Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="Shell32">
<Guid>{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
<Visible>False</Visible>
<ProductName>Windows Installer 4.5</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishUrlHistory />
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>en-US</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,216 @@
using System;
//using System.Collections.Generic;
using System.IO;
//using System.Linq;
//using Shell32;
//using IWshRuntimeLibrary;
//using System.Threading;
namespace PinTo10v2
{
class Program
{
static readonly string help = "\n\r" + "PinTo10v2 Version 1.1" + "\n\r" + "\n\r" + "This command line tool pins files to the Windows 7 & 10 Taskbar and Start Menu" + "\n\r" + "\n\r" +
"Please note that pinning a shortcut that already exists in the Start Menu folder" + "\r\n" + "structure to the Start Menu is quicker than pinning a file with no existing" + "\r\n" + "Start Menu shortcut." +
"\n\r" + "\n\r" + "Syntax: PinTo10v2 [/pintb | /unpintb | /pinsm | /unpinsm] " + "'filename'" + "\n\r" + "\n\r" + "pintb = Pin to the Task Bar" + "\n\r" +
"unpintb = Unpin from the Task Bar" + "\n\r" + "pinsm = Pin to the Start Menu" + "\n\r" + "unpinsm = Unpin from the Start Menu";
static int Main(string[] args)
{
bool pin = true;
bool taskbar = false;
bool startmenu = false;
bool dosomework = false;
bool needtomakeshortcut = false;
string fileName = "";
string osversionfromreg = Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion", "ProductName", "nullvalue").ToString();
string win10 = "Windows 10";
string win7 = "Windows 7";
bool iswin10 = osversionfromreg.Contains(win10);
bool iswin7 = osversionfromreg.Contains(win7);
var actionIndex = pin ? 51201 : 51394;
if (args.Length < 1)
{
Console.WriteLine(help);
Environment.Exit(0);
}
if (args.Length >= 1)
{
if (args[0].ToLower() == "/?")
{
Console.WriteLine(help);
Environment.Exit(0);
}
}
if (args.Length >= 1)
{
if (args[0].ToLower() == "-help")
{
Console.WriteLine(help);
Environment.Exit(0);
}
}
if (iswin10)
{
actionIndex = pin ? 51201 : 51394;
}
if (iswin7)
{
actionIndex = pin ? 5381 : 5382;
}
if (!iswin10)
{
if (!iswin7)
{
Console.WriteLine("\n\r" + "I only work on windows 7 & 10 - Exiting...");
Environment.Exit(0);
}
}
if (args.Length >= 2)
{
if (args[0].ToLower() == "/pintb")
{
pin = true;
taskbar = true;
dosomework = true;
}
else if (args[0].ToLower() == "/unpintb")
{
pin = false;
taskbar = true;
dosomework = true;
}
if (args[0].ToLower() == "/pinsm")
{
pin = true;
startmenu = true;
dosomework = true;
}
else if (args[0].ToLower() == "/unpinsm")
{
pin = false;
startmenu = true;
dosomework = true;
}
else
{
if (dosomework == false)
{
Console.WriteLine(help);
Environment.Exit(0);
}
}
fileName = args[1];
}
if (!System.IO.File.Exists(fileName))
{
Console.WriteLine("\n\r" + "Specified file not found. Exiting...");
Environment.Exit(1);
}
string pathtofile = Path.GetDirectoryName(fileName);
string wholefileName = Path.GetFileName(fileName);
string extension = Path.GetExtension(wholefileName);
string filenamenoextension = Path.GetFileNameWithoutExtension(wholefileName);
bool success = true;
// Check that the verb exists on the file specified before continuing ////////////////////////////////////////////////
if (!startmenu) Utils.ChangeImagePathName("explorer.exe");
success = Utils.CheckifVerbExists(fileName, pin, startmenu);
if (!success)
{
Console.WriteLine("\n\r" + "Can't find the pin / unpin verb on the file specified. Exiting...");
Environment.Exit(1);
}
if (success)
{
//Console.WriteLine("Verb found on the file specified. Continuing...");
}
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (startmenu == true)
{
if (extension == ".lnk")
{
// Search for files in Start Menu //
string allusersprofile = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData).ToString();
string[] searchalluserstart = Directory.GetFiles(allusersprofile + @"\Microsoft\Windows\Start Menu", wholefileName, SearchOption.AllDirectories);
string appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string currentuserstart = appdata + @"\Microsoft\Windows\Start Menu\Programs";
string[] searchcurrentuserstart = Directory.GetFiles(currentuserstart, wholefileName, SearchOption.AllDirectories);
if (searchalluserstart.Length == 0)
{
//Console.WriteLine("Not found in all users start");
if (searchcurrentuserstart.Length == 0)
{
needtomakeshortcut = false;
//Console.WriteLine("Not found in current user's start");
System.IO.File.Copy(args[1], appdata + @"\Microsoft\Windows\Start Menu\Programs\" + wholefileName, true);
if (!System.IO.File.Exists(appdata + @"\Microsoft\Windows\Start Menu\Programs\" + wholefileName))
{
Console.WriteLine("\n\r" + "Shortcut not copied to Start Menu. Exiting...");
Environment.Exit(1);
}
}
}
}
if (extension != ".lnk")
{
// Search for files in Start Menu //
string allusersprofile = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData).ToString();
string[] searchalluserstart = Directory.GetFiles(allusersprofile + @"\Microsoft\Windows\Start Menu\Programs", filenamenoextension + @".lnk", SearchOption.AllDirectories);
string appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string currentuserstart = appdata + @"\Microsoft\Windows\Start Menu\Programs";
string[] searchcurrentuserstart = Directory.GetFiles(currentuserstart, filenamenoextension + @".lnk", SearchOption.AllDirectories); //search for equivalent .lnk file in the Start Menu
if (searchalluserstart.Length == 0)
{
if (searchcurrentuserstart.Length == 0)
{
needtomakeshortcut = true;
}
}
}
}
try
{
if (taskbar)
{
Utils.ChangeImagePathName("explorer.exe");
success = Utils.PinUnpinTaskbar(fileName, pin);
if (success) Utils.RestoreImagePathName();
}
if (startmenu)
{
if (extension == ".lnk")
{
Utils.PinUnpinStart(fileName, pin);
}
if (extension != ".lnk")
{
if (pin) // only create shortcut if pinning and not unpinning
{
if (needtomakeshortcut)
{
Utils.CreateShortcut(args[1]);
}
}
Utils.PinUnpinStart(fileName, pin);
}
}
}
finally
{
}
//Console.WriteLine(success ? "OK" : "Failed");
return success ? 0 : 1;
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
//using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("PinTo10v2")]
[assembly: AssemblyDescription("Pin a program to the Task Bar or Start Menu in Windows 7 or 10")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Stuart Pearson")]
[assembly: AssemblyProduct("PinTo10v2")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("3ba34e28-32de-4bd1-b182-d8c821196196")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]

View File

@@ -0,0 +1,490 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using ComTypes = System.Runtime.InteropServices.ComTypes;
namespace PinTo10v2
{
// Based on https://emoacht.wordpress.com/2012/11/14/csharp-appusermodelid/
// Modified from http://smdn.jp/programming/tips/createlnk/
// Originally from http://www.vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects/Creating_and_Modifying_Shortcuts/article.asp
// Partly based on Sending toast notifications from desktop apps sample
// Heavily based on work by Alex Weinberger http://alexweinberger.com/main/pinning-network-program-taskbar-programmatically-windows-10/
// Modified to add Start Menu functionality to both Windows 7 and 10
public class ShellLink : IDisposable
{
#region Win32 and COM
// IShellLink Interface
[ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("000214F9-0000-0000-C000-000000000046")]
private interface IShellLinkW
{
uint GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile,
int cchMaxPath, ref WIN32_FIND_DATAW pfd, uint fFlags);
uint GetIDList(out IntPtr ppidl);
uint SetIDList(IntPtr pidl);
uint GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName,
int cchMaxName);
uint SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
uint GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir,
int cchMaxPath);
uint SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
uint GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs,
int cchMaxPath);
uint SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
uint GetHotKey(out ushort pwHotkey);
uint SetHotKey(ushort wHotKey);
uint GetShowCmd(out int piShowCmd);
uint SetShowCmd(int iShowCmd);
uint GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
int cchIconPath, out int piIcon);
uint SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
uint SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel,
uint dwReserved);
uint Resolve(IntPtr hwnd, uint fFlags);
uint SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
}
// ShellLink CoClass (ShellLink object)
[ComImport,
ClassInterface(ClassInterfaceType.None),
Guid("00021401-0000-0000-C000-000000000046")]
private class CShellLink { }
// WIN32_FIND_DATAW Structure
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
private struct WIN32_FIND_DATAW
{
public uint dwFileAttributes;
public ComTypes.FILETIME ftCreationTime;
public ComTypes.FILETIME ftLastAccessTime;
public ComTypes.FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
// IPropertyStore Interface
[ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")]
private interface IPropertyStore
{
uint GetCount([Out] out uint cProps);
uint GetAt([In] uint iProp, out PropertyKey pkey);
uint GetValue([In] ref PropertyKey key, [Out] PropVariant pv);
uint SetValue([In] ref PropertyKey key, [In] PropVariant pv);
uint Commit();
}
// PropertyKey Structure
// Narrowed down from PropertyKey.cs of Windows API Code Pack 1.1
[StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct PropertyKey
{
#region Fields
private Guid formatId; // Unique GUID for property
private Int32 propertyId; // Property identifier (PID)
#endregion
#region Public Properties
public Guid FormatId
{
get
{
return formatId;
}
}
public Int32 PropertyId
{
get
{
return propertyId;
}
}
#endregion
#region Constructor
public PropertyKey(Guid formatId, Int32 propertyId)
{
this.formatId = formatId;
this.propertyId = propertyId;
}
public PropertyKey(string formatId, Int32 propertyId)
{
this.formatId = new Guid(formatId);
this.propertyId = propertyId;
}
#endregion
}
// PropVariant Class (only for string value)
// Narrowed down from PropVariant.cs of Windows API Code Pack 1.1
// Originally from http://blogs.msdn.com/b/adamroot/archive/2008/04/11
// /interop-with-propvariants-in-net.aspx
[StructLayout(LayoutKind.Explicit)]
private sealed class PropVariant : IDisposable
{
#region Fields
[FieldOffset(0)]
ushort valueType; // Value type
// [FieldOffset(2)]
// ushort wReserved1; // Reserved field
// [FieldOffset(4)]
// ushort wReserved2; // Reserved field
// [FieldOffset(6)]
// ushort wReserved3; // Reserved field
[FieldOffset(8)]
IntPtr ptr; // Value
#endregion
#region Public Properties
// Value type (System.Runtime.InteropServices.VarEnum)
public VarEnum VarType
{
get { return (VarEnum)valueType; }
set { valueType = (ushort)value; }
}
// Whether value is empty or null
public bool IsNullOrEmpty
{
get
{
return (valueType == (ushort)VarEnum.VT_EMPTY ||
valueType == (ushort)VarEnum.VT_NULL);
}
}
// Value (only for string value)
public string Value
{
get
{
return Marshal.PtrToStringUni(ptr);
}
}
#endregion
#region Constructor
public PropVariant()
{ }
// Construct with string value
public PropVariant(string value)
{
if (value == null)
throw new ArgumentException("Failed to set value.");
valueType = (ushort)VarEnum.VT_LPWSTR;
ptr = Marshal.StringToCoTaskMemUni(value);
}
#endregion
#region Destructor
~PropVariant()
{
Dispose();
}
public void Dispose()
{
PropVariantClear(this);
GC.SuppressFinalize(this);
}
#endregion
}
[DllImport("Ole32.dll", PreserveSig = false)]
private extern static void PropVariantClear([In, Out] PropVariant pvar);
#endregion
#region Fields
private IShellLinkW shellLinkW = null;
// Name = System.AppUserModel.ID
// ShellPKey = PKEY_AppUserModel_ID
// FormatID = 9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3
// PropID = 5
// Type = String (VT_LPWSTR)
private readonly PropertyKey AppUserModelIDKey =
new PropertyKey("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}", 5);
private const int MAX_PATH = 260;
private const int INFOTIPSIZE = 1024;
private const int STGM_READ = 0x00000000; // STGM constants
private const uint SLGP_UNCPRIORITY = 0x0002; // SLGP flags
#endregion
#region Private Properties (Interfaces)
private IPersistFile PersistFile
{
get
{
IPersistFile PersistFile = shellLinkW as IPersistFile;
if (PersistFile == null)
throw new COMException("Failed to create IPersistFile.");
else
return PersistFile;
}
}
private IPropertyStore PropertyStore
{
get
{
IPropertyStore PropertyStore = shellLinkW as IPropertyStore;
if (PropertyStore == null)
throw new COMException("Failed to create IPropertyStore.");
else
return PropertyStore;
}
}
#endregion
#region Public Properties (Minimal)
// Path of loaded shortcut file
public string ShortcutFile
{
get
{
string shortcutFile;
PersistFile.GetCurFile(out shortcutFile);
return shortcutFile;
}
}
// Path of target file
public string TargetPath
{
get
{
// No limitation to length of buffer string in the case of Unicode though.
StringBuilder targetPath = new StringBuilder(MAX_PATH);
WIN32_FIND_DATAW data = new WIN32_FIND_DATAW();
VerifySucceeded(shellLinkW.GetPath(targetPath, targetPath.Capacity, ref data,
SLGP_UNCPRIORITY));
return targetPath.ToString();
}
set
{
VerifySucceeded(shellLinkW.SetPath(value));
}
}
// Path to start the target in
public string StartIn
{
get
{
// No limitation to length of buffer string in the case of Unicode though.
StringBuilder targetPath = new StringBuilder(MAX_PATH);
VerifySucceeded(shellLinkW.GetWorkingDirectory(targetPath, targetPath.Capacity));
return targetPath.ToString();
}
set
{
VerifySucceeded(shellLinkW.SetWorkingDirectory(value));
}
}
public string Arguments
{
get
{
// No limitation to length of buffer string in the case of Unicode though.
StringBuilder arguments = new StringBuilder(INFOTIPSIZE);
VerifySucceeded(shellLinkW.GetArguments(arguments, arguments.Capacity));
return arguments.ToString();
}
set
{
VerifySucceeded(shellLinkW.SetArguments(value));
}
}
// AppUserModelID to be used for Windows 7 or later.
public string AppUserModelID
{
get
{
using (PropVariant pv = new PropVariant())
{
VerifySucceeded(PropertyStore.GetValue(AppUserModelIDKey, pv));
if (pv.Value == null)
return "Null";
else
return pv.Value;
}
}
set
{
using (PropVariant pv = new PropVariant(value))
{
VerifySucceeded(PropertyStore.SetValue(AppUserModelIDKey, pv));
VerifySucceeded(PropertyStore.Commit());
}
}
}
public string IconLocation
{
get
{
// No limitation to length of buffer string in the case of Unicode though.
StringBuilder pszIconPath = new StringBuilder(INFOTIPSIZE);
int piIcon;
VerifySucceeded(shellLinkW.GetIconLocation(pszIconPath, pszIconPath.Capacity, out piIcon));
return pszIconPath.ToString() + ", " + piIcon;
}
set
{
var parts = value.Split(',');
var pszIconPath = parts[0];
int iIcon = 0;
if (parts.Length > 1)
int.TryParse(parts[1], out iIcon);
VerifySucceeded(shellLinkW.SetIconLocation(pszIconPath, iIcon));
}
}
#endregion
#region Constructor
public ShellLink()
: this(null)
{ }
// Construct with loading shortcut file.
public ShellLink(string file)
{
try
{
shellLinkW = (IShellLinkW)new CShellLink();
}
catch
{
throw new COMException("Failed to create ShellLink object.");
}
if (file != null)
Load(file);
}
#endregion
#region Destructor
~ShellLink()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (shellLinkW != null)
{
// Release all references.
Marshal.FinalReleaseComObject(shellLinkW);
shellLinkW = null;
}
}
#endregion
#region Methods
// Save shortcut file.
public void Save()
{
string file = ShortcutFile;
if (file == null)
throw new InvalidOperationException("File name is not given.");
else
Save(file);
}
public void Save(string file)
{
if (file == null)
throw new ArgumentNullException("File name is required.");
else
PersistFile.Save(file, true);
}
// Load shortcut file.
public void Load(string file)
{
if (!File.Exists(file))
throw new FileNotFoundException("File is not found.", file);
else
PersistFile.Load(file, STGM_READ);
}
// Verify if operation succeeded.
public static void VerifySucceeded(uint hresult)
{
if (hresult > 1)
throw new InvalidOperationException("Failed with HRESULT: " +
hresult.ToString("X"));
}
#endregion
}
}

View File

@@ -0,0 +1,312 @@
using System;
//using System.Collections.Generic;
using System.IO;
//using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
//using Shell32;
using IWshRuntimeLibrary;
//using System.Threading.Tasks;
namespace PinTo10v2
{
static public class Utils
{
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static string originalImagePathName;
static int unicodeSize = IntPtr.Size * 2;
static void GetPointers(out IntPtr imageOffset, out IntPtr imageBuffer)
{
IntPtr pebBaseAddress = GetBasicInformation().PebBaseAddress;
var processParameters = Marshal.ReadIntPtr(pebBaseAddress, 4 * IntPtr.Size);
imageOffset = processParameters.Increment(4 * 4 + 5 * IntPtr.Size + unicodeSize + IntPtr.Size + unicodeSize);
imageBuffer = Marshal.ReadIntPtr(imageOffset, IntPtr.Size);
}
internal static void ChangeImagePathName(string newFileName)
{
IntPtr imageOffset, imageBuffer;
GetPointers(out imageOffset, out imageBuffer);
//Read original data
var imageLen = Marshal.ReadInt16(imageOffset);
originalImagePathName = Marshal.PtrToStringUni(imageBuffer, imageLen / 2);
var newImagePathName = Path.Combine(Path.GetDirectoryName(originalImagePathName), newFileName);
if (newImagePathName.Length > originalImagePathName.Length) throw new Exception("new ImagePathName cannot be longer than the original one");
//Write the string, char by char
var ptr = imageBuffer;
foreach (var unicodeChar in newImagePathName)
{
Marshal.WriteInt16(ptr, unicodeChar);
ptr = ptr.Increment(2);
}
Marshal.WriteInt16(ptr, 0);
//Write the new length
Marshal.WriteInt16(imageOffset, (short)(newImagePathName.Length * 2));
}
internal static void RestoreImagePathName()
{
IntPtr imageOffset, ptr;
GetPointers(out imageOffset, out ptr);
foreach (var unicodeChar in originalImagePathName)
{
Marshal.WriteInt16(ptr, unicodeChar);
ptr = ptr.Increment(2);
}
Marshal.WriteInt16(ptr, 0);
Marshal.WriteInt16(imageOffset, (short)(originalImagePathName.Length * 2));
}
public static ProcessBasicInformation GetBasicInformation()
{
uint status;
ProcessBasicInformation pbi;
int retLen;
var handle = System.Diagnostics.Process.GetCurrentProcess().Handle;
if ((status = NtQueryInformationProcess(handle, 0,
out pbi, Marshal.SizeOf(typeof(ProcessBasicInformation)), out retLen)) >= 0xc0000000)
throw new Exception("Windows exception. status=" + status);
return pbi;
}
[DllImport("ntdll.dll")]
public static extern uint NtQueryInformationProcess(
[In] IntPtr ProcessHandle,
[In] int ProcessInformationClass,
[Out] out ProcessBasicInformation ProcessInformation,
[In] int ProcessInformationLength,
[Out] [Optional] out int ReturnLength
);
public static IntPtr Increment(this IntPtr ptr, int value)
{
unchecked
{
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(ptr.ToInt32() + value);
else
return new IntPtr(ptr.ToInt64() + value);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct ProcessBasicInformation
{
public uint ExitStatus;
public IntPtr PebBaseAddress;
public IntPtr AffinityMask;
public int BasePriority;
public IntPtr UniqueProcessId;
public IntPtr InheritedFromUniqueProcessId;
}
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
internal static extern IntPtr LoadLibrary(string lpLibFileName);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
internal static extern int LoadString(IntPtr hInstance, uint wID, StringBuilder lpBuffer, int nBufferMax);
// //////////////////////////////////////////////////////////////////////
public static void CreateShortcut(string targetFileLocation)
{
string currentuserstart = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Microsoft\Windows\Start Menu\Programs";
string wholefileName = Path.GetFileName(targetFileLocation);
string extension = Path.GetExtension(wholefileName);
string filenamenoextension = Path.GetFileNameWithoutExtension(wholefileName);
string DirectoryName = Path.GetDirectoryName(targetFileLocation);
string shortcutLocation = currentuserstart + @"\" + filenamenoextension + ".lnk"; //System.IO.Path.Combine(Environment.SpecialFolder.StartMenu.ToString(), "Dummy.lnk");
WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutLocation);
//shortcut.Description = ""; // The description of the shortcut
shortcut.WorkingDirectory = DirectoryName; // The "Start in" path of the new shortcut
shortcut.TargetPath = targetFileLocation; // The path of the file that will launch when the shortcut is run
shortcut.Save(); // Save the shortcut
}
public static bool PinUnpinTaskbar(string filePath, bool pin)
{
if (!System.IO.File.Exists(filePath))
{
Console.WriteLine("\n\r" + "Specified file not found. Exiting...");
Environment.Exit(1);
};
//throw new FileNotFoundException(filePath);
int MAX_PATH = 255;
var actionIndex = pin ? 5386 : 5387; // 5386 is the DLL index for"Pin to Tas&kbar", ref. http://www.win7dll.info/shell32_dll.html
StringBuilder szPinToStartLocalized = new StringBuilder(MAX_PATH);
IntPtr hShell32 = LoadLibrary("Shell32.dll");
LoadString(hShell32, (uint)actionIndex, szPinToStartLocalized, MAX_PATH);
string localizedVerb = szPinToStartLocalized.ToString();
string path = Path.GetDirectoryName(filePath);
string fileName = Path.GetFileName(filePath);
// create the shell application object
dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic directory = shellApplication.NameSpace(path);
dynamic link = directory.ParseName(fileName);
dynamic verbs = link.Verbs();
for (int i = 0; i < verbs.Count(); i++)
{
dynamic verb = verbs.Item(i);
var name = verb.Name;
//Console.WriteLine("Verb Name = " + name);
if (verb.Name.Equals(localizedVerb))
{
//Console.WriteLine("Trying to do it...");
verb.DoIt();
return true;
}
}
return false;
}
// //////////////////////////////////////////////////////////////////////
public static bool PinUnpinStart(string filePath, bool pin)
{
//Console.WriteLine("Pinning to Start...");
if (!System.IO.File.Exists(filePath)) throw new FileNotFoundException(filePath);
int MAX_PATH = 255;
StringBuilder szPinToStartLocalized = new StringBuilder(MAX_PATH);
StringBuilder szInvPinToStartLocalized = new StringBuilder(MAX_PATH);
IntPtr hShell32 = LoadLibrary("Shell32.dll");
string osversionfromreg = Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion", "ProductName", "nullvalue").ToString();
string win10 = "Windows 10";
string win7 = "Windows 7";
bool iswin10 = osversionfromreg.Contains(win10);
bool iswin7 = osversionfromreg.Contains(win7);
var actionIndex = pin ? 51201 : 51394;
var invActionIndex = pin ? 51394 : 51201;
if (iswin10)
{
actionIndex = pin ? 51201 : 51394;
invActionIndex = pin ? 51394 : 51201;
}
if (iswin7)
{
actionIndex = pin ? 5381 : 5382;
invActionIndex = pin ? 5382 : 5381;
}
LoadString(hShell32, (uint)actionIndex, szPinToStartLocalized, MAX_PATH);
string localizedVerb = szPinToStartLocalized.ToString();
LoadString(hShell32, (uint)invActionIndex, szInvPinToStartLocalized, MAX_PATH);
string invLocalizedVerb = szInvPinToStartLocalized.ToString();
string path = Path.GetDirectoryName(filePath);
string fileName = Path.GetFileName(filePath);
// create the shell application object
dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic directory = shellApplication.NameSpace(path);
dynamic link = directory.ParseName(fileName);
dynamic verbs = link.Verbs();
int counter = 0;
while (1 == 1) // setup a loop to keep trying to pin to start - will try 20 times at 500ms interval and then fail if not successful
{
shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
directory = shellApplication.NameSpace(path);
link = directory.ParseName(fileName);
verbs = link.Verbs();
for (int i = 0; i < verbs.Count(); i++)
{
dynamic verb = verbs.Item(i);
if (verb.Name.Equals(localizedVerb))
{
verb.DoIt();
System.Threading.Thread.Sleep(500);
counter = counter = + 1;
}
if (verb.Name.Equals(invLocalizedVerb)) // check for the existance of the opposite verb to confirm if it's been successful
{
//Console.WriteLine("I think it's done! Exiting...");
return true;
}
if (counter == 20) // Try 20 times (10 seconds) and then fail...
{
return false;
}
}
}
}
public static bool CheckifVerbExists(string filePath, bool pin, bool startmenu)
{
//Console.WriteLine("Pinning to Start...");
if (!System.IO.File.Exists(filePath)) throw new FileNotFoundException(filePath);
int MAX_PATH = 255;
StringBuilder szPinToStartLocalized = new StringBuilder(MAX_PATH);
StringBuilder szInvPinToStartLocalized = new StringBuilder(MAX_PATH);
IntPtr hShell32 = LoadLibrary("Shell32.dll");
string osversionfromreg = Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion", "ProductName", "nullvalue").ToString();
string win10 = "Windows 10";
string win7 = "Windows 7";
bool iswin10 = osversionfromreg.Contains(win10);
bool iswin7 = osversionfromreg.Contains(win7);
var actionIndex = pin ? 51201 : 51394;
var invActionIndex = pin ? 51394 : 51201;
if (iswin10)
{
if (startmenu)
{
actionIndex = pin ? 51201 : 51394;
}
if (!startmenu)
{
actionIndex = pin ? 5386 : 5387;
}
}
if (iswin7)
{
if (startmenu)
{
actionIndex = pin ? 5381 : 5382;
}
if (!startmenu)
{
actionIndex = pin ? 5386 : 5387;
}
}
LoadString(hShell32, (uint)actionIndex, szPinToStartLocalized, MAX_PATH);
string localizedVerb = szPinToStartLocalized.ToString();
string path = Path.GetDirectoryName(filePath);
string fileName = Path.GetFileName(filePath);
// create the shell application object
dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic directory = shellApplication.NameSpace(path);
dynamic link = directory.ParseName(fileName);
dynamic verbs = link.Verbs();
for (int i = 0; i < verbs.Count(); i++)
{
dynamic verb = verbs.Item(i);
var name = verb.Name;
//Console.WriteLine("Verb name = " + name);
if (verb.Name.Equals(localizedVerb))
{
// verb.DoIt();
return true;
}
}
return false;
}
}
}

View File

@@ -0,0 +1,35 @@
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\Interop.IWshRuntimeLibrary.dll
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\Interop.Shell32.dll
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\Pinto10v2.csproj.ResolveComReference.cache
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\Pinto10v2.csprojResolveAssemblyReference.cache
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\bin\Debug\Pinto10v2.exe.config
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\bin\Debug\Pinto10v2.exe
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\bin\Debug\Pinto10v2.pdb
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\Pinto10v2.exe
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\Pinto10v2.pdb
C:\Users\stuar\Desktop\PinTo10v2_1.0\Pinto10v2\bin\Debug\Pinto10v2.exe.config
C:\Users\stuar\Desktop\PinTo10v2_1.0\Pinto10v2\obj\Debug\Interop.IWshRuntimeLibrary.dll
C:\Users\stuar\Desktop\PinTo10v2_1.0\Pinto10v2\obj\Debug\Interop.Shell32.dll
C:\Users\stuar\Desktop\PinTo10v2_1.0\Pinto10v2\obj\Debug\Pinto10v2.csproj.ResolveComReference.cache
C:\Users\stuar\Desktop\PinTo10v2_1.0\Pinto10v2\obj\Debug\Pinto10v2.exe
C:\Users\stuar\Desktop\PinTo10v2_1.0\Pinto10v2\obj\Debug\Pinto10v2.pdb
C:\Users\stuar\Desktop\PinTo10v2_1.0\Pinto10v2\bin\Debug\Pinto10v2.exe
C:\Users\stuar\Desktop\PinTo10v2_1.0\Pinto10v2\bin\Debug\Pinto10v2.pdb
C:\Users\stuar\Desktop\PinTo10v2_1.0\Pinto10v2\obj\Debug\Pinto10v2.csprojResolveAssemblyReference.cache
C:\Users\stuar\Desktop\PinTo10v2_1.0\Source\Pinto10v2\bin\Debug\Pinto10v2.exe.config
C:\Users\stuar\Desktop\PinTo10v2_1.0\Source\Pinto10v2\obj\Debug\Interop.IWshRuntimeLibrary.dll
C:\Users\stuar\Desktop\PinTo10v2_1.0\Source\Pinto10v2\obj\Debug\Interop.Shell32.dll
C:\Users\stuar\Desktop\PinTo10v2_1.0\Source\Pinto10v2\obj\Debug\Pinto10v2.csproj.ResolveComReference.cache
C:\Users\stuar\Desktop\PinTo10v2_1.0\Source\Pinto10v2\obj\Debug\Pinto10v2.exe
C:\Users\stuar\Desktop\PinTo10v2_1.0\Source\Pinto10v2\obj\Debug\Pinto10v2.pdb
C:\Users\stuar\Desktop\PinTo10v2_1.0\Source\Pinto10v2\bin\Debug\Pinto10v2.exe
C:\Users\stuar\Desktop\PinTo10v2_1.0\Source\Pinto10v2\bin\Debug\Pinto10v2.pdb
C:\Users\stuar\Desktop\PinTo10v2_1.0\Source\Pinto10v2\obj\Debug\Pinto10v2.csprojResolveAssemblyReference.cache
C:\Users\stuar\Desktop\Updated\Pinto10v2\bin\Debug\Pinto10v2.exe.config
C:\Users\stuar\Desktop\Updated\Pinto10v2\obj\Debug\Interop.IWshRuntimeLibrary.dll
C:\Users\stuar\Desktop\Updated\Pinto10v2\obj\Debug\Interop.Shell32.dll
C:\Users\stuar\Desktop\Updated\Pinto10v2\obj\Debug\Pinto10v2.csproj.ResolveComReference.cache
C:\Users\stuar\Desktop\Updated\Pinto10v2\obj\Debug\Pinto10v2.exe
C:\Users\stuar\Desktop\Updated\Pinto10v2\obj\Debug\Pinto10v2.pdb
C:\Users\stuar\Desktop\Updated\Pinto10v2\bin\Debug\Pinto10v2.exe
C:\Users\stuar\Desktop\Updated\Pinto10v2\bin\Debug\Pinto10v2.pdb

View File

@@ -0,0 +1,27 @@
C:\Users\stuar\Desktop\test2\PintoTB10\bin\Debug\PintoTB10.exe.config
C:\Users\stuar\Desktop\test2\PintoTB10\bin\Debug\PintoTB10.exe
C:\Users\stuar\Desktop\test2\PintoTB10\bin\Debug\PintoTB10.pdb
C:\Users\stuar\Desktop\test2\PintoTB10\obj\Debug\PintoTB10.csprojResolveAssemblyReference.cache
C:\Users\stuar\Desktop\test2\PintoTB10\obj\Debug\PintoTB10.exe
C:\Users\stuar\Desktop\test2\PintoTB10\obj\Debug\PintoTB10.pdb
C:\Users\stuar\Desktop\test2\PintoTB10\obj\Debug\Interop.IWshRuntimeLibrary.dll
C:\Users\stuar\Desktop\test2\PintoTB10\obj\Debug\Interop.Shell32.dll
C:\Users\stuar\Desktop\test2\PintoTB10\obj\Debug\PintoTB10.csproj.ResolveComReference.cache
C:\Users\stuar\Desktop\PinTo10v2_2\PintoTB10\bin\Debug\PintoTB10.exe.config
C:\Users\stuar\Desktop\PinTo10v2_2\PintoTB10\obj\Debug\Interop.IWshRuntimeLibrary.dll
C:\Users\stuar\Desktop\PinTo10v2_2\PintoTB10\obj\Debug\Interop.Shell32.dll
C:\Users\stuar\Desktop\PinTo10v2_2\PintoTB10\obj\Debug\PintoTB10.csproj.ResolveComReference.cache
C:\Users\stuar\Desktop\PinTo10v2_2\PintoTB10\obj\Debug\PintoTB10.exe
C:\Users\stuar\Desktop\PinTo10v2_2\PintoTB10\obj\Debug\PintoTB10.pdb
C:\Users\stuar\Desktop\PinTo10v2_2\PintoTB10\bin\Debug\PintoTB10.exe
C:\Users\stuar\Desktop\PinTo10v2_2\PintoTB10\bin\Debug\PintoTB10.pdb
C:\Users\stuar\Desktop\PinTo10v2_2\PintoTB10\obj\Debug\PintoTB10.csprojResolveAssemblyReference.cache
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\bin\Debug\PintoTB10.exe.config
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\Interop.IWshRuntimeLibrary.dll
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\Interop.Shell32.dll
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\PintoTB10.csproj.ResolveComReference.cache
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\PintoTB10.exe
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\PintoTB10.pdb
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\obj\Debug\PintoTB10.csprojResolveAssemblyReference.cache
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\bin\Debug\PintoTB10.exe
C:\Users\stuar\Desktop\PinTo10v3\PintoTB10\bin\Debug\PintoTB10.pdb