using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace GeekDesk.Util { public class Functions { public static string GetShortcutTarget(string file) { try { if (System.IO.Path.GetExtension(file).ToLower() != ".lnk") { throw new Exception("Supplied file must be a .LNK file"); } FileStream fileStream = File.Open(file, FileMode.Open, FileAccess.Read); using (System.IO.BinaryReader fileReader = new BinaryReader(fileStream)) { fileStream.Seek(0x14, SeekOrigin.Begin); // Seek to flags uint flags = fileReader.ReadUInt32(); // Read flags if ((flags & 1) == 1) { // Bit 1 set means we have to // skip the shell item ID list fileStream.Seek(0x4c, SeekOrigin.Begin); // Seek to the end of the header uint offset = fileReader.ReadUInt16(); // Read the length of the Shell item ID list fileStream.Seek(offset, SeekOrigin.Current); // Seek past it (to the file locator info) } long fileInfoStartsAt = fileStream.Position; // Store the offset where the file info // structure begins uint totalStructLength = fileReader.ReadUInt32(); // read the length of the whole struct fileStream.Seek(0xc, SeekOrigin.Current); // seek to offset to base pathname uint fileOffset = fileReader.ReadUInt32(); // read offset to base pathname // the offset is from the beginning of the file info struct (fileInfoStartsAt) fileStream.Seek((fileInfoStartsAt + fileOffset), SeekOrigin.Begin); // Seek to beginning of // base pathname (target) long pathLength = (totalStructLength + fileInfoStartsAt) - fileStream.Position - 2; // read // the base pathname. I don't need the 2 terminating nulls. char[] linkTarget = fileReader.ReadChars((int)pathLength); // should be unicode safe var link = new string(linkTarget); int begin = link.IndexOf("\0\0"); if (begin > -1) { int end = link.IndexOf("\\\\", begin + 2) + 2; end = link.IndexOf('\0', end) + 1; string firstPart = link.Substring(0, begin); string secondPart = link.Substring(end); return firstPart + secondPart; } else { return link; } } } catch { return ""; } } } class Program { static void Main(string[] args) { if (args.Length == 0) { System.Console.WriteLine("Please try again with a file path"); } else { System.Console.WriteLine("LNK File: " + args[0]); System.Console.WriteLine("LNK Path: " + Functions.GetShortcutTarget(args[0])); } } } }