public static string GetErrorMsg(uint id) { char[] buf = new char[256]; if (Win32Import.FormatMessage( Win32Import.FormatMessage_Flag.FromSystem, null, id, 0, buf, buf.Length, IntPtr.Zero) > 0) { return(new string(buf)); } return(string.Empty); }
public static DateTime?GetRegstryKeyLastWriteTime(IntPtr rootKey, string path) { IntPtr key = IntPtr.Zero; if (Win32Import.RegOpenKeyEx(rootKey, path, 0, 0x20019, ref key) == 0) { ulong[] fileTime = new ulong[1]; if (Win32Import.RegQueryInfoKey( key, null, null, 0, null, null, null, null, null, null, null, fileTime) == 0) { return(DateTime.FromFileTimeUtc(unchecked ((long)fileTime[0])).ToLocalTime()); } Win32Import.RegCloseKey(key); } return(null); }
public static bool WinExecAndWait(string cmd, uint timeout) { var startupInfo = new Win32Import.StartupInfo(); startupInfo.cb = (uint)Marshal.SizeOf(startupInfo); var processInfo = new Win32Import.Process_Information(); Win32Import.Win32Bool r = Win32Import.CreateProcess(null, cmd.ToCharArray(), IntPtr.Zero, IntPtr.Zero, 0, 0, null, null, ref startupInfo, ref processInfo); if (r == Win32Import.Win32Bool.False) { return(false); } Win32Import.WaitForSingleObject(processInfo.hProcess, timeout); Win32Import.CloseHandle(processInfo.hThread); Win32Import.CloseHandle(processInfo.hProcess); return(true); }
static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += (o, e) => { MessageBox.Show(e.ExceptionObject.ToString(), "发生错误!"); }; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); List <UinstallItem> itemList = PrepareUinstallList(); Form form = new Form(); form.Text = "软件卸载助手 v1.0"; form.Size = new Size(800, 500); form.StartPosition = FormStartPosition.CenterScreen; DataGridView grid = new DataGridView(); grid.Dock = DockStyle.Fill; grid.ReadOnly = true; grid.SelectionMode = DataGridViewSelectionMode.FullRowSelect; grid.MultiSelect = false; grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; grid.RowHeadersVisible = false; grid.AllowUserToResizeRows = false; grid.AllowUserToResizeColumns = false; grid.CellBorderStyle = DataGridViewCellBorderStyle.RaisedHorizontal; grid.DataSource = itemList; form.Controls.Add(grid); StatusStrip statusBar = new StatusStrip(); statusBar.Dock = DockStyle.Bottom; form.Controls.Add(statusBar); ToolStripStatusLabel statusLabelItemCnt = new ToolStripStatusLabel(); statusLabelItemCnt.TextAlign = ContentAlignment.MiddleLeft; statusLabelItemCnt.Width = 90; statusLabelItemCnt.BorderSides = ToolStripStatusLabelBorderSides.All; statusBar.Items.Add(statusLabelItemCnt); ToolStripStatusLabel statusLabelSearchStr = new ToolStripStatusLabel(); statusLabelSearchStr.Spring = true; statusLabelSearchStr.TextAlign = ContentAlignment.MiddleLeft; statusBar.Items.Add(statusLabelSearchStr); // 单击列头,排序 bool ascendingSort = true; grid.ColumnHeaderMouseClick += (o, e) => { var column = grid.Columns[e.ColumnIndex]; { Type t = column.ValueType; if (t.IsGenericType && t.GetGenericTypeDefinition().FullName == "System.Nullable`1") { t = t.GetGenericArguments()[0]; } if (t.GetInterface("IComparable") == null) { return; } } grid.ScrollBars = ScrollBars.None; grid.DataSource = null; ascendingSort = !ascendingSort; var fGet = MakeGetPropertyFunc(typeof(UinstallItem).GetProperty(column.DataPropertyName)); itemList.Sort((x, y) => { int r = 0; object valX = fGet(x); object valY = fGet(y); if (valX == null && valY == null) { r = 0; } else if (valX == null) { r = -1; } else if (valY == null) { r = 1; } else { r = (valX as IComparable).CompareTo(valY); } return(ascendingSort ? r : -r); }); grid.DataSource = itemList; grid.ScrollBars = ScrollBars.Both; }; // 控制显示的列数 int visibleColumn = 4; Action adjustGridColumnFunc = () => { for (int i = 0; i < grid.Columns.Count; ++i) { var column = grid.Columns[i]; column.Width = (typeof(UinstallItem).GetProperty(column.DataPropertyName). GetCustomAttributes(typeof(DisplayWidth), false)[0] as DisplayWidth).Width; column.Visible = i < visibleColumn; } }; grid.DataBindingComplete += (o, e) => { adjustGridColumnFunc(); statusLabelItemCnt.Text = string.Format("共有{0}个项目", itemList.Count); }; // 右键菜单 ContextMenuStrip contextMenu = new ContextMenuStrip(); contextMenu.Items.Add("详细信息").Click += (o, e) => { visibleColumn = 104 - visibleColumn; adjustGridColumnFunc(); }; contextMenu.Items.Add(string.Format(AppConfig.BrowseWow64 ? "兼容软件" : "非兼容软件")).Click += (o, e) => { AppConfig.BrowseWow64 = !AppConfig.BrowseWow64; Win32Import.WinExec(Environment.CommandLine, 5); form.Close(); }; contextMenu.Items.Add("关于").Click += (o, e) => { MessageBox.Show("Scan制作!", "关于"); }; MouseEventHandler mouseHandlerShowMenu = (o, e) => { if (e.Button == MouseButtons.Right) { contextMenu.Show(grid, e.Location); } }; grid.MouseClick += mouseHandlerShowMenu; form.MouseClick += mouseHandlerShowMenu; // 输入定位; 包括把form和grid的输入字符都交给输入框 TextBox searchTextBox = new TextBox(); searchTextBox.Location = new Point(-5, -5); searchTextBox.Size = new Size(1, 1); searchTextBox.ImeMode = ImeMode.On; searchTextBox.TextChanged += (o, e) => { statusLabelSearchStr.Text = ""; if (string.IsNullOrEmpty(searchTextBox.Text)) { return; } statusLabelSearchStr.Text = string.Format("搜索:{0}", searchTextBox.Text); int idx = 0; foreach (string name in itemList.Select(n => n.DisplayName)) { if (name.StartsWith(searchTextBox.Text, StringComparison.OrdinalIgnoreCase)) { Program.Assert(idx >= 0 && idx < grid.Rows.Count); grid.CurrentCell = grid.Rows[idx].Cells[0]; break; } ++idx; } }; form.Controls.Add(searchTextBox); grid.MouseClick += (o, e) => { searchTextBox.Text = string.Empty; }; KeyPressEventHandler keyPressFunc = (o, e) => { if (char.IsControl(e.KeyChar)) { return; } searchTextBox.Text += e.KeyChar; searchTextBox.SelectionStart = searchTextBox.Text.Length; }; PreviewKeyDownEventHandler previewKeyDownFunc = (o, e) => { if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Escape || e.KeyCode == Keys.Enter) { return; } searchTextBox.Focus(); }; form.KeyPress += keyPressFunc; grid.KeyPress += keyPressFunc; form.PreviewKeyDown += previewKeyDownFunc; grid.PreviewKeyDown += previewKeyDownFunc; // 弹出详细信息 grid.DoubleClick += (o, e) => { if (grid.SelectedRows == null || grid.SelectedRows.Count == 0) { return; } int idx = grid.SelectedRows[0].Index; Program.Assert(idx >= 0 && idx < itemList.Count); TryUninstallItem(itemList[idx]); }; // esc,退出 KeyEventHandler escHandler = (o, e) => { if (e.KeyCode == Keys.Escape) { form.Close(); } }; form.KeyUp += escHandler; grid.KeyUp += escHandler; searchTextBox.KeyUp += escHandler; // 检测列表中的项目是否已经从注册表中删除,是的话重启 var registryChangeDetectTimer = new System.Windows.Forms.Timer(); registryChangeDetectTimer.Interval = 1000; registryChangeDetectTimer.Tick += (o, e) => { using (RegistryKey uninstallKey = OpenUninstallRegistryKey(false)) { List <string> subKeyNames = uninstallKey.GetSubKeyNames().ToList(); subKeyNames.Sort(); foreach (UinstallItem item in itemList) { if (subKeyNames.BinarySearch(item.RegistryKey) < 0) { Win32Import.WinExec(Environment.CommandLine, 5); form.Close(); break; } } } }; registryChangeDetectTimer.Start(); Application.Run(form); }
static void TryUninstallItem(UinstallItem item) { Form form = new Form(); form.Size = new Size(350, 300); form.Text = item.DisplayName; form.StartPosition = FormStartPosition.CenterScreen; FlowLayoutPanel btnPanel = new FlowLayoutPanel(); btnPanel.Dock = DockStyle.Bottom; btnPanel.FlowDirection = FlowDirection.LeftToRight; btnPanel.BorderStyle = BorderStyle.FixedSingle; btnPanel.Height = 30; Button btnInstallFolder = new Button() { Text = "安装目录" }; btnInstallFolder.Enabled = !string.IsNullOrEmpty(item.InstallFolder); btnInstallFolder.Click += (o, e) => { Win32Import.ShellExecute(form.Handle, "open", item.InstallFolder, null, null, 5); }; btnPanel.Controls.Add(btnInstallFolder); Button btnUninstall = new Button() { Text = "卸载" }; btnUninstall.Enabled = !string.IsNullOrEmpty(item.UninstallCmd); btnUninstall.Click += (o, e) => { if (Win32Import.WinExec(item.UninstallCmd, 5) > 31) { form.Close(); } else { MessageBox.Show( "卸载的过程中发生异常!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }; btnPanel.Controls.Add(btnUninstall); Button btnDel = new Button() { Text = "删除" }; btnDel.Click += (o, e) => { if (!string.IsNullOrEmpty(item.UninstallCmd) && MessageBox.Show( "检测到该软件自带卸载功能,仍然要强制从安装列表中删除项目吗?", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) { return; } if (MessageBox.Show("这项操作具有很高的风险,你仍然要继续吗?", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) { return; } using (RegistryKey k = OpenUninstallRegistryKey(true)) { k.DeleteSubKey(item.RegistryKey); form.Close(); } }; btnPanel.Controls.Add(btnDel); Button btnClose = new Button() { Text = "关闭" }; btnClose.Click += (o, e) => { form.Close(); }; btnPanel.Controls.Add(btnClose); PropertyGrid grid = new PropertyGrid(); grid.Dock = DockStyle.Fill; grid.PropertySort = PropertySort.NoSort; grid.ToolbarVisible = false; grid.SelectedObject = item; form.Controls.Add(grid); form.Controls.Add(btnPanel); // esc处理 KeyEventHandler escKeyupHandler = (o, e) => { if (e.KeyCode == Keys.Escape) { form.Close(); } }; form.KeyPreview = true; form.KeyUp += escKeyupHandler; form.ShowDialog(); form.Dispose(); }
static bool BuildUinstallItem(RegistryKey itemKey, ref UinstallItem item) { string IconPEPath = string.Empty; // 先准备最容易得到的数据 item.RegistryKey = itemKey.Name.Substring(itemKey.Name.LastIndexOf('\\') + 1); item.DisplayName = GetStringValueFromRegistry(itemKey, "DisplayName"); // item.QuietUninstall = itemKey.GetValue("QuietUninstallString", string.Empty).ToString(); item.UninstallCmd = GetStringValueFromRegistry(itemKey, "UninstallString"); IconPEPath = GetStringValueFromRegistry(itemKey, "DisplayIcon"); item.InstallFolder = GetStringValueFromRegistry(itemKey, "InstallLocation"); item.Version = GetStringValueFromRegistry(itemKey, "DisplayVersion"); item.CompanyName = GetStringValueFromRegistry(itemKey, "Publisher"); try { string s = GetStringValueFromRegistry(itemKey, "InstallDate"); if (!string.IsNullOrEmpty(s)) { item.InstallDate = DateTime.ParseExact(s, "yyyyMMdd", null); } } catch { item.InstallDate = null; } // 得到重要的中间数据PEPath string PEPath = string.Empty; if (!string.IsNullOrEmpty(IconPEPath)) { Match m = Regex.Match(IconPEPath, "\\p{L}:[^?<>|:\"]+?\\.exe"); if (m.Success) { PEPath = m.Groups[0].ToString(); } } if (string.IsNullOrEmpty(PEPath) && !string.IsNullOrEmpty(item.UninstallCmd)) { Match m = Regex.Match(item.UninstallCmd, "\\p{L}:[^?<>|:\"]+?\\.exe"); if (m.Success) { PEPath = m.Groups[0].ToString(); } } if (string.IsNullOrEmpty(PEPath) && !string.IsNullOrEmpty(item.InstallFolder)) { string[] files = Directory.GetFiles(item.InstallFolder, "*.exe"); if (files != null && files.Length > 0) { PEPath = files[0]; } } // 根据PEPath反过来可以尝试修正一些数据 if (!string.IsNullOrEmpty(PEPath)) { if (string.IsNullOrEmpty(IconPEPath)) { IconPEPath = PEPath; } if (string.IsNullOrEmpty(item.InstallFolder)) { item.InstallFolder = Path.GetDirectoryName(PEPath); } } // 读取PEPath文件中的内容,修正一些数据 if (!string.IsNullOrEmpty(PEPath)) { Win32Wrap.FileVersionInfo info = Win32Wrap.GetFileVersionInfo(PEPath); if (info.langBasedInfoList != null && info.langBasedInfoList.Length > 0) { Win32Wrap.FileVersionInfo.LanguageBasedFileInfo lanBasedInfo = info.langBasedInfoList[0]; item.Description = lanBasedInfo.fileDescription; if (string.IsNullOrEmpty(item.DisplayName) && !string.IsNullOrEmpty(lanBasedInfo.productName)) { item.DisplayName = lanBasedInfo.productName; } if (string.IsNullOrEmpty(item.CompanyName) && !string.IsNullOrEmpty(lanBasedInfo.companyName)) { item.CompanyName = lanBasedInfo.companyName; } if (string.IsNullOrEmpty(item.Version) && !string.IsNullOrEmpty(lanBasedInfo.productVersion)) { item.Version = lanBasedInfo.productVersion; } } } if (!string.IsNullOrEmpty(IconPEPath)) { int iconIdx = 0; IntPtr[] smallIcon = new IntPtr[1]; { Match m = Regex.Match(IconPEPath, "(.+),(\\d)$"); if (m.Success) { try { IconPEPath = m.Groups[1].ToString(); iconIdx = int.Parse(m.Groups[2].ToString()); } catch { } } } if (IconPEPath.Length > 2 && IconPEPath.StartsWith("\"") && IconPEPath.EndsWith("\"")) { IconPEPath = IconPEPath.Substring(1, IconPEPath.Length - 2); } if (Win32Import.ExtractIconEx(IconPEPath, 0, null, smallIcon, 1) > 0 && smallIcon[0] != IntPtr.Zero) { item.PEIcon = Icon.FromHandle(smallIcon[0]); } } if (item.PEIcon == null) { IntPtr[] smallIcon = new IntPtr[1]; if (Win32Import.ExtractIconEx("shell32.dll", 2, null, smallIcon, 1) > 0 && smallIcon[0] != IntPtr.Zero) { item.PEIcon = Icon.FromHandle(smallIcon[0]); } } // 修正安装日期 if (item.InstallDate == null) { item.InstallDate = Win32Wrap.GetRegstryKeyLastWriteTime( Win32Import.HKEY_LOCAL_MACHINE, itemKey.Name.Substring(itemKey.Name.IndexOf('\\') + 1)); } // 保证显示的数据存在 if (string.IsNullOrEmpty(item.DisplayName) && !string.IsNullOrEmpty(PEPath)) { item.DisplayName = Path.GetFileNameWithoutExtension(PEPath); } return(!string.IsNullOrEmpty(item.DisplayName)); }
public static FileVersionInfo GetFileVersionInfo(string path) { uint unuse = 0; uint bufSize = Win32Import.GetFileVersionInfoSize(path, ref unuse); if (bufSize != 0) { byte[] buf = new byte[bufSize]; if (Win32Import.GetFileVersionInfo(path, 0, bufSize, buf) != 0) { FileVersionInfo fileVersionInfo = new FileVersionInfo(); IntPtr data = IntPtr.Zero; uint dataSize = 0; if (Win32Import.VerQueryValue(buf, @"\", ref data, ref dataSize) > 0 && dataSize == Marshal.SizeOf(fileVersionInfo.fixedInfo)) { fileVersionInfo.fixedInfo = (Win32Import.VS_FixedFileInfo)Marshal.PtrToStructure( data, typeof(Win32Import.VS_FixedFileInfo)); } short[] langCodeList = null; if (Win32Import.VerQueryValue(buf, @"\VarFileInfo\Translation", ref data, ref dataSize) > 0) { langCodeList = new short[dataSize / 2]; Marshal.Copy(data, langCodeList, 0, langCodeList.Length); } if (langCodeList != null) { fileVersionInfo.langBasedInfoList = new FileVersionInfo.LanguageBasedFileInfo[langCodeList.Length / 2]; for (int i = 0; i < fileVersionInfo.langBasedInfoList.Length; ++i) { FileVersionInfo.LanguageBasedFileInfo langBasedInfo = new FileVersionInfo.LanguageBasedFileInfo(); langBasedInfo.language = unchecked ((ushort)langCodeList[i * 2]); langBasedInfo.codePage = unchecked ((ushort)langCodeList[i * 2 + 1]); Func <string, string> verQueryString = s => { string fmt = string.Format( "\\StringFileInfo\\{0:x4}{1:x4}\\{2}", langBasedInfo.language, langBasedInfo.codePage, s); if (Win32Import.VerQueryValue(buf, fmt, ref data, ref dataSize) > 0) { char[] tempBuf = new char[dataSize / 2]; Marshal.Copy(data, tempBuf, 0, tempBuf.Length); return(new string(tempBuf)); } return(string.Empty); }; langBasedInfo.comments = verQueryString("Comments"); langBasedInfo.internalName = verQueryString("InternalName");; langBasedInfo.productName = verQueryString("ProductName");; langBasedInfo.companyName = verQueryString("CompanyName");; langBasedInfo.legalCopyright = verQueryString("LegalCopyright");; langBasedInfo.productVersion = verQueryString("ProductVersion");; langBasedInfo.fileDescription = verQueryString("FileDescription");; langBasedInfo.legalTrademarks = verQueryString("LegalTrademarks");; langBasedInfo.privateBuild = verQueryString("PrivateBuild");; langBasedInfo.fileVersion = verQueryString("FileVersion");; langBasedInfo.originalFilename = verQueryString("OriginalFilename");; langBasedInfo.specialBuild = verQueryString("SpecialBuild");; fileVersionInfo.langBasedInfoList[i] = langBasedInfo; } } return(fileVersionInfo); } } return(new FileVersionInfo()); }
public static string GetLastErrorMsg() { return(GetErrorMsg(Win32Import.GetLastError())); }