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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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();
        }
Beispiel #6
0
        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()));
 }