diff --git a/App.config b/App.config index 3847826..8705f81 100644 --- a/App.config +++ b/App.config @@ -28,7 +28,7 @@ - + diff --git a/Constant/Constants.cs b/Constant/Constants.cs index eae0885..1cda463 100644 --- a/Constant/Constants.cs +++ b/Constant/Constants.cs @@ -11,7 +11,7 @@ namespace GeekDesk.Constant public static string APP_DIR = AppDomain.CurrentDomain.BaseDirectory.Trim(); // 是否为开发模式 - public static bool DEV = false; + public static bool DEV = true; public static string MY_NAME = DEV ? "GeekDesk-D" : "GeekDesk"; diff --git a/Control/UserControls/Config/MotionControl.xaml b/Control/UserControls/Config/MotionControl.xaml index 5605c17..45bd7e4 100644 --- a/Control/UserControls/Config/MotionControl.xaml +++ b/Control/UserControls/Config/MotionControl.xaml @@ -50,6 +50,16 @@ + + + + + + + + + + diff --git a/Control/UserControls/PannelCard/RightCardControl.xaml b/Control/UserControls/PannelCard/RightCardControl.xaml index 807e4ba..8f517be 100644 --- a/Control/UserControls/PannelCard/RightCardControl.xaml +++ b/Control/UserControls/PannelCard/RightCardControl.xaml @@ -99,7 +99,7 @@ hc:Poptip.Content="{Binding Content}" hc:Poptip.Placement="BottomLeft" Background="#00FFFFFF" - MouseLeftButtonUp="IconClick" + MouseLeftButtonDown="IconClick" MouseEnter="StackPanel_MouseEnter" MouseLeave="StackPanel_MouseLeave" > diff --git a/Control/UserControls/PannelCard/RightCardControl.xaml.cs b/Control/UserControls/PannelCard/RightCardControl.xaml.cs index f86cebe..89d7ebc 100644 --- a/Control/UserControls/PannelCard/RightCardControl.xaml.cs +++ b/Control/UserControls/PannelCard/RightCardControl.xaml.cs @@ -66,15 +66,30 @@ namespace GeekDesk.Control.UserControls.PannelCard /// private void IconClick(object sender, MouseButtonEventArgs e) { - IconInfo icon = (IconInfo)((SimpleStackPanel)sender).Tag; - if (icon.AdminStartUp) + if (appData.AppConfig.DoubleOpen && e.ClickCount >= 2) { - StartIconApp(icon, IconStartType.ADMIN_STARTUP); - } - else + IconInfo icon = (IconInfo)((SimpleStackPanel)sender).Tag; + if (icon.AdminStartUp) + { + StartIconApp(icon, IconStartType.ADMIN_STARTUP); + } + else + { + StartIconApp(icon, IconStartType.DEFAULT_STARTUP); + } + } else if (!appData.AppConfig.DoubleOpen && e.ClickCount == 1) { - StartIconApp(icon, IconStartType.DEFAULT_STARTUP); + IconInfo icon = (IconInfo)((SimpleStackPanel)sender).Tag; + if (icon.AdminStartUp) + { + StartIconApp(icon, IconStartType.ADMIN_STARTUP); + } + else + { + StartIconApp(icon, IconStartType.DEFAULT_STARTUP); + } } + } /// @@ -159,6 +174,23 @@ namespace GeekDesk.Control.UserControls.PannelCard p.StartInfo.Arguments = "/e,/select," + icon.Path; break; } + } else + { + if (appData.AppConfig.AppHideType == AppHideType.START_EXE) + { + //如果开启了贴边隐藏 则窗体不贴边才隐藏窗口 + if (appData.AppConfig.MarginHide) + { + if (!MainWindow.hide.IsMargin()) + { + MainWindow.HideApp(); + } + } + else + { + MainWindow.HideApp(); + } + } } p.Start(); icon.Count++; diff --git a/GeekDesk.csproj b/GeekDesk.csproj index d67ab1b..6906e6d 100644 --- a/GeekDesk.csproj +++ b/GeekDesk.csproj @@ -195,6 +195,7 @@ + @@ -367,6 +368,15 @@ False True + + {50A7E9B0-70EF-11D1-B75A-00A0C90564FE} + 1 + 0 + 0 + tlbimp + False + True + \ No newline at end of file diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 1f3f085..bee513c 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -49,5 +49,5 @@ using System.Windows; //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 //通过使用 "*",如下所示: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.3.2.1")] -[assembly: AssemblyFileVersion("2.3.2.1")] +[assembly: AssemblyVersion("2.4.1.0")] +[assembly: AssemblyFileVersion("2.4.1.0")] diff --git a/Update.json b/Update.json index 0f98be2..ce0db6b 100644 --- a/Update.json +++ b/Update.json @@ -1,9 +1,9 @@ { "title": "GeekDesk版本更新", - "subTitle": "V2.3.21", + "subTitle": "V2.4.10", "msgTitle": "本次更新内容如下", - "msg": "['所有窗口可Esc退出','修复一个测试遗留BUG,导致没有D盘的情况下无法添加项目','修复已知问题']", + "msg": "['']", "githubUrl": "https://github.com/Demo-Liu/GeekDesk/releases", "giteeUrl": "https://gitee.com/demo_liu/GeekDesk/releases", - "version": "2.3.21" + "version": "2.4.10" } \ No newline at end of file diff --git a/Util/FileIcon.cs b/Util/FileIcon.cs index 1acc48b..9f0460c 100644 --- a/Util/FileIcon.cs +++ b/Util/FileIcon.cs @@ -36,7 +36,7 @@ namespace GeekDesk.Util public static BitmapImage GetBitmapImage(string filePath) { - Icon ico; + Icon ico = null; //选中文件中的图标总数 var iconTotalCount = PrivateExtractIcons(filePath, 0, 0, 0, null, null, 0, 0); //用于接收获取到的图标指针 @@ -53,12 +53,20 @@ namespace GeekDesk.Util { ip = hIcons[0]; ico = Icon.FromHandle(ip); + if (IsMinOrTransparent(ico)) + { + ico = null; + } } - else if (GetBlurExts().Contains(ext)) + if (ico == null && GetBlurExts().Contains(ext)) { ico = Icon.ExtractAssociatedIcon(filePath); + if (IsMinOrTransparent(ico)) + { + ico = null; + } } - else + if (ico == null) { ip = GetJumboIcon(GetIconIndex(filePath)); ico = Icon.FromHandle(ip); @@ -86,6 +94,36 @@ namespace GeekDesk.Util return bmpImage.Clone(); } + + private static bool IsMinOrTransparent(Icon ico) + { + Bitmap bm = ico.ToBitmap(); + double w = bm.Width; + double h = bm.Height; + + Color middleColor = bm.GetPixel((int)(w * 0.50), (int)(h * 0.50)); + Color transparent = Color.FromArgb(0, 0, 0, 0); + + //如果中间像素不为空 直接判断此icon不为空 + if (middleColor != Color.Transparent && middleColor != transparent) + { + return false; + } + + //判断中间一条横线像素 有不透明元素即判断 icon不为空 + Color c; + int h2 = (int)h / 2; + for (int i=0; i<(int)w; i++) + { + c = bm.GetPixel(i, h2); + if (c!= Color.Transparent && c != transparent) + { + return false; + } + } + return true; + } + private static ImageCodecInfo GetEncoderInfo(String mimeType) { int j; @@ -416,7 +454,6 @@ namespace GeekDesk.Util int iOverlay, ref int piIndex); }; - } } diff --git a/Util/FileUtil.cs b/Util/FileUtil.cs index 3eb823a..e5d100b 100644 --- a/Util/FileUtil.cs +++ b/Util/FileUtil.cs @@ -2,7 +2,9 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace GeekDesk.Util @@ -10,6 +12,8 @@ namespace GeekDesk.Util public class FileUtil { + private static readonly string NO_PATH = ".*{.*}.*"; + public static string GetTargetPathByLnk(string filePath) { try @@ -21,7 +25,12 @@ namespace GeekDesk.Util { return null; } - return shortcut.TargetPath; + string path = shortcut.TargetPath; + if (path==null || Regex.IsMatch(path, NO_PATH)) + { + path = ParseShortcut(filePath); + } + return path; } #pragma warning disable CS0168 // 声明了变量“e”,但从未使用过 catch (Exception e) @@ -30,5 +39,73 @@ namespace GeekDesk.Util return null; } } + + + /* + UINT MsiGetShortcutTarget( + LPCTSTR szShortcutTarget, + LPTSTR szProductCode, + LPTSTR szFeatureId, + LPTSTR szComponentCode + ); + */ + [DllImport("msi.dll", CharSet = CharSet.Auto)] + static extern int MsiGetShortcutTarget(string targetFile, StringBuilder productCode, StringBuilder featureID, StringBuilder componentCode); + + public enum InstallState + { + NotUsed = -7, + BadConfig = -6, + Incomplete = -5, + SourceAbsent = -4, + MoreData = -3, + InvalidArg = -2, + Unknown = -1, + Broken = 0, + Advertised = 1, + Removed = 1, + Absent = 2, + Local = 3, + Source = 4, + Default = 5 + } + + public const int MaxFeatureLength = 38; + public const int MaxGuidLength = 38; + public const int MaxPathLength = 1024; + + /* + INSTALLSTATE MsiGetComponentPath( + LPCTSTR szProduct, + LPCTSTR szComponent, + LPTSTR lpPathBuf, + DWORD* pcchBuf + ); + */ + [DllImport("msi.dll", CharSet = CharSet.Auto)] + static extern InstallState MsiGetComponentPath(string productCode, string componentCode, StringBuilder componentPath, ref int componentPathBufferSize); + + public static string ParseShortcut(string file) + { + StringBuilder product = new StringBuilder(MaxGuidLength + 1); + StringBuilder feature = new StringBuilder(MaxFeatureLength + 1); + StringBuilder component = new StringBuilder(MaxGuidLength + 1); + + MsiGetShortcutTarget(file, product, feature, component); + + int pathLength = MaxPathLength; + StringBuilder path = new StringBuilder(pathLength); + + InstallState installState = MsiGetComponentPath(product.ToString(), component.ToString(), path, ref pathLength); + if (installState == InstallState.Local) + { + return path.ToString(); + } + else + { + return null; + } + } + } } diff --git a/Util/Functions.cs b/Util/Functions.cs new file mode 100644 index 0000000..d5b3bf7 --- /dev/null +++ b/Util/Functions.cs @@ -0,0 +1,87 @@ +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])); + } + } + } +} \ No newline at end of file diff --git a/ViewModel/AppConfig.cs b/ViewModel/AppConfig.cs index fa3a435..122f2d8 100644 --- a/ViewModel/AppConfig.cs +++ b/ViewModel/AppConfig.cs @@ -70,7 +70,22 @@ namespace GeekDesk.ViewModel private bool showBarIcon = true; //显示托盘图标 默认显示 + private bool doubleOpen = false; //双击打开项目 默认关闭 + #region GetSet + public bool DoubleOpen + { + get + { + return doubleOpen; + } + set + { + doubleOpen = value; + OnPropertyChanged("DoubleOpen"); + } + } + public bool ShowBarIcon { get